{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Java 17 Quick Syntax Reference\n",
    "https://www.demo2s.com/java/java-17-introduction.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Java程序的基本结构\n",
    "一个Java程序的基本结构主要包括以下几个部分：\n",
    "1. 包（Package）：包是用来组织类和接口的，它们定义了一个命名空间，其中包含类和其他的包。例如：package hello;\n",
    "2. 类（Class）：Java程序的基本单位是类。一个类定义了一种数据类型，这种数据类型由类的方法（行为）和字段（状态）组成。例如：public class Structure { ... }。\n",
    "3. 主方法（Main Method）：Java程序的执行入口是main()方法。例如：public static void main(String[] args) { ... }。\n",
    "4. 标识符（Identifiers）：标识符是Java程序员定义的一种符号，用来代表包、类、方法、变量等的名称。\n",
    "5. 关键字（Keywords）：关键字是Java语言预先定义的单词，用于表示特定的语法结构。例如：public, class, static, void等。\n",
    "6. 语句（Statements）：语句是执行操作的一段源代码。\n",
    "7. 注释（Comments）：注释是用来解释代码的，提高程序的可读性。例如：// 这是一个注释。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Java Notebook 环境安装\n",
    "1. 从https://github.com/dflib/jjava/releases下载最新版本的jjava-xxxx-py3-none-any.whl\n",
    "2. 在Python环境中安装Notebook和jjava-xxxx-py3-none-any.whl\n",
    "3. 重启vscode\n",
    "4. 内核选择Java"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **01 Hello World**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// package myproject;\n",
    "public class MyApp \n",
    "{\n",
    "  public static void main(String[] args) \n",
    "  {\n",
    "    System.out.print(\"Hello World\");\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World"
     ]
    }
   ],
   "source": [
    "// ** 01 Hello World **\n",
    "System.out.print(\"Hello World\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **02 Compile and Run**\n",
    "\n",
    "编译和运行\n",
    "\n",
    "```shell\n",
    "$ javac Hello.java\n",
    "$ java Hello\n",
    "Hello, world!\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// single-line comment\n",
    " \n",
    "/* multi-line\n",
    "   comment */\n",
    "\n",
    "/** javadoc\n",
    "    comment */"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在Java中，我们有三种主要的注释方式： \n",
    "1. 单行注释：以双斜杠//开始，用于注释一行内的代码。例如：// 这是一个单行注释。 \n",
    "2. 多行注释：以/*开始，以*/结束，用于注释多行代码。例如：/*这是一个多行注释*/\n",
    "3. 文档注释：以/**开始，以*/结束，一般用于对类和方法进行说明，可以使用javadoc工具生成API文档。例如：/**这是一个文档注释，用于生成API文档 */"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 变量的命名规则\n",
    "\n",
    "在Java中，变量的命名需要遵循以下规则1：\n",
    "1. 首字母：变量名必须以字母、下划线（_）或美元符号（$）开头。\n",
    "2. 其他部分：除开头外，变量名可以包含字母、数字、下划线和美元符号。\n",
    "3. 关键字：变量名不能使用Java的保留字（例如，public、class等）。\n",
    "4. 大小写敏感：Java是大小写敏感的，因此变量名中的大小写字母被视为不同的符号。例如，myVariable和myvariable是两个不同的变量。\n",
    "5. 不以数字开头：变量名不能以数字开头，但可以包含数字。\n",
    "\n",
    "此外，Java中还有一些命名约定： \n",
    "1. 驼峰命名法（Camel Case）：在变量名中使用驼峰命名法，即将每个单词的首字母大写，除了第一个单词外，其余单词的首字母都采用大写形式。例如：myVariableName。 \n",
    "2. 有意义的名字：变量名应该具有清晰的含义，能够准确地反映变量的用途。避免使用单个字符或无意义的缩写。 \n",
    "3. 避免关键字：不要使用Java关键字（例如，class、int、boolean等）作为变量名"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **03 Variables**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10"
     ]
    }
   ],
   "source": [
    "// Declaration\n",
    "int myInt;\n",
    "\n",
    "// Assignment\n",
    "myInt = 10;\n",
    "\n",
    "// Output\n",
    "System.out.print(myInt); // \"10\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 原始数据类型\n",
    "\n",
    "| 数据类型 | 大小   | 默认 | 范围               |\n",
    "|-----------|--------|---------|---------------------|\n",
    "| `byte`    | 1 byte | 0       | -128 ^to^ 127       |\n",
    "| `short`   | 2 byte | 0       | -2^15^ ^to^ 2^15^-1 |\n",
    "| `int`     | 4 byte | 0       | -2^31^ ^to^ 2^31^-1 |\n",
    "| `long`    | 8 byte | 0       | -2^63^ ^to^ 2^63^-1 |\n",
    "| `float`   | 4 byte | 0.0f    | _N/A_               |\n",
    "| `double`  | 8 byte | 0.0d    | _N/A_               |\n",
    "| `char`    | 2 byte | \\\\u0000 | 0 ^to^ 65535        |\n",
    "| `boolean` | _N/A_  | false   | true / false        |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "byte  myInt8  = 2;  // -128   to +127\n",
    "short myInt16 = 1;  // -32768 to +32767\n",
    "int   myInt32 = 0;  // -2^31  to +2^31-1\n",
    "long  myInt64 = -1; // -2^63  to +2^63-1\n",
    "\n",
    "int myHex = 0xF;  // hexadecimal (base 16)\n",
    "int myOct = 07;   // octal (base 8)\n",
    "int myBin = 0b10; // binary (base 2) \n",
    "\n",
    "int bigNumber = 10_000_000;\n",
    "\n",
    "double myDouble = 3.14;\n",
    "       myDouble = 3e2; // 3*10^2 = 300\n",
    "\n",
    "float myFloat = 3.14F;\n",
    "      myFloat = (float)3.14;\n",
    "\n",
    "char myChar = 'A';\n",
    "     myChar = '\\u0000'; // \\u0000 to \\uFFFF\n",
    "\n",
    "boolean myBool = false;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false,
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Anonymous block\n",
    "public static void main(String[] args) \n",
    "{\n",
    "  // Anonymous code block\n",
    "  {\n",
    "    int localVar = 10;\n",
    "  }\n",
    "  // localVar is unavailable from here\n",
    "}\n",
    "\n",
    "// Type inference\n",
    "public static void main(String[] args) \n",
    "{\n",
    "  var i = 5; // Implicit type\n",
    "  int ii = 5; // Explicit type\n",
    "  var a = new java.util.ArrayList();\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 类型转换 Type Casting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "10.0"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// Widening\n",
    "// byte<short<int<long<float<double\n",
    "int i = 10;\n",
    "long l = i;               // 10\n",
    "// Narrowing \n",
    "double d = 10.02;\n",
    "long l = (long)d;         // 10\n",
    "String.valueOf(10);       // \"10\"\n",
    "Integer.parseInt(\"10\");   // 10\n",
    "Double.parseDouble(\"10\"); // 10.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 交换变量 Swap"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2\n",
      "2 1\n"
     ]
    }
   ],
   "source": [
    "int a = 1;\n",
    "int b = 2;\n",
    "System.out.println(a + \" \" + b); // 1 2\n",
    "int temp = a;\n",
    "a = b;\n",
    "b = temp;\n",
    "System.out.println(a + \" \" + b); // 2 1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **04 Operators**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// Arithmetic operators\n",
    "float f = 3+2; // 5 // addition\n",
    "      f = 3-2; // 1 // subtraction\n",
    "      f = 3*2; // 6 // multiplication\n",
    "      f = 3/2; // 1 // division\n",
    "      f = 3%2; // 1 // modulus (division remainder)\n",
    "\n",
    "// Combined assignment operators\n",
    "int i = 0;\n",
    "    i += 5; // i = i+5;\n",
    "    i -= 5; // i = i-5;\n",
    "    i *= 5; // i = i*5; \n",
    "    i /= 5; // i = i/5;\n",
    "    i %= 5; // i = i%5;\n",
    "\n",
    "// Increment and decrement operators\n",
    "++i; // i += 1\n",
    "--i; // i -= 1\n",
    "\n",
    "++i; // pre-increment\n",
    "--i; // pre-decrement     \n",
    "i++; // post-increment\n",
    "i--; // post-decrement\n",
    "\n",
    "int j;\n",
    "i = 5; j = i++; // j=5, i=6   \n",
    "i = 5; j = ++i; // j=6, i=6\n",
    "\n",
    "// Comparison operators\n",
    "boolean b = (2==3); // equal to (false)\n",
    "        b = (2!=3); // not equal to (true)\n",
    "        b = (2>3);  // greater than (false)\n",
    "        b = (2<3);  // less than (true)\n",
    "        b = (2>=3); // greater than or equal to (false)\n",
    "        b = (2<=3); // less than or equal to (true)\n",
    "\n",
    "// Logical operators\n",
    "boolean b = (true && false); // logical and (false)\n",
    "        b = (true || false); // logical or (true)\n",
    "        b = !(true);         // logical not (false)\n",
    "\n",
    "// Bitwise operators\n",
    "byte b = 5 & 4;  // 101 & 100 = 100 (4) // and\n",
    "     b = 5 | 4;  // 101 | 100 = 101 (5) // or\n",
    "     b = 5 ^ 4;  // 101 ^ 100 = 001 (1) // xor\n",
    "     b = 4 << 1; // 100 << 1 = 1000 (8) // left shift\n",
    "     b = 4 >> 1; // 100 >> 1 = 10 (2) // right shift\n",
    "     b = 4 >>>1; // 100 >>>1 = 10 (2) // zero-fill right shift\n",
    "     b = ~4;     // ~00000100 = 11111011 (-5) // invert\n",
    "\n",
    "int i = 5;\n",
    "    i &= 4;   // \"and\" and assign\n",
    "    i |= 4;   // or and assign\n",
    "    i ^= 4;   // xor and assign\n",
    "    i <<= 1;  // left shift and assign\n",
    "    i >>= 1;  // right shift and assign\n",
    "    i >>>= 1; // right shift and assign (move sign bit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **05 String**\n",
    "\n",
    "在Java中，字符串是一个特殊的类，被广泛应用在Java编程中。Java没有内置的字符串类型，而是在标准Java类库中提供了一个String类来创建和操作字符串。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\n",
      " World\n",
      "Hello World\n"
     ]
    }
   ],
   "source": [
    "String a = \"Hello\";\n",
    "String b = new String(\" World\");\n",
    "\n",
    "String c = a+b; // Hello World\n",
    "       a += b;  // Hello World\n",
    "\n",
    "// String compare\n",
    "boolean x = a.equals(b); // compares string\n",
    "boolean y = (a == b);    // compares address\n",
    "boolean z = \"Hello\".equals(a);\n",
    "\n",
    "// StringBuffer class\n",
    "StringBuffer sb = new StringBuffer(\"Hello\");\n",
    "\n",
    "sb.append(\" World\");   // add to end of string\n",
    "System.out.println(sb);\n",
    "sb.delete(0, 5);       // remove 5 first characters\n",
    "System.out.println(sb);\n",
    "sb.insert(0, \"Hello\"); // insert string at beginning\n",
    "System.out.println(sb);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "String s = sb.toString();\n",
    "\n",
    "// Text blocks\n",
    "String textBlock = \"\"\"\n",
    "line 1\n",
    "line 2\"\"\";\n",
    "\n",
    "String html = \"\"\"\n",
    "              <div>\n",
    "                <p>Hi</p>\n",
    "              </div>\"\"\";"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "John Doe\n"
     ]
    }
   ],
   "source": [
    "String first = \"John\";\n",
    "String last = \"Doe\";\n",
    "String name = first + \" \" + last;\n",
    "System.out.println(name);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "String str1 = \"value\"; \n",
    "String str2 = new String(\"value\");\n",
    "String str3 = String.valueOf(123);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "Scanner in = new Scanner(System.in);\n",
    "String str = in.nextLine();\n",
    "System.out.println(str);\n",
    "int num = in.nextInt();\n",
    "System.out.println(num);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **06 Arrays**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**一维数组**\n",
    "\n",
    "在Java中，数组是一种基本的数据结构，用于存储相同类型的多个值。可以使用以下语法来声明和初始化一个数组：\n",
    "``` java\n",
    "dataType[] arrayName = new dataType[arraySize];\n",
    "```\n",
    "其中，dataType 是数组元素的数据类型，arrayName 是数组的名称，arraySize 是数组的大小。例如，可以创建一个包含10个整数的数组：\n",
    "``` java\n",
    "int[] myArray = new int[10];\n",
    "```\n",
    "也可以在声明数组时就为其赋值：\n",
    "``` java\n",
    "int[] myArray = {1, 2, 3, 4, 5};\n",
    "```\n",
    "数组的元素可以通过索引（从0开始）来访问和修改。例如，myArray[0] 就是数组的第一个元素。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "6"
     ]
    }
   ],
   "source": [
    "// Array declaration \n",
    "int[] x;\n",
    "int y[];\n",
    "\n",
    "// Array allocation\n",
    "int y[] = new int[3];\n",
    "\n",
    "// Array assignment\n",
    "y[0] = 1;\n",
    "y[1] = 2;\n",
    "y[2] = 3;\n",
    "\n",
    "int[] x = new int[] {1,2,3};\n",
    "int[] x = {1,2,3};\n",
    "\n",
    "// Array access\n",
    "System.out.print(x[0] + x[1] + x[2]); // \"6\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**二维数组**\n",
    "\n",
    "二维数组可以看作是一个表格，第一个下标表示行，第二个下标表示列。二维数组的创建和初始化与一维数组类似，它其实就是一个把多个一维数组包起来的数组。例如：\n",
    "```java\n",
    "int[][] arrayName = new int[length1][length2]; // 创建并初始化二维数组\n",
    "```\n",
    "二维数组的元素可以通过两个下标来获取。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0011"
     ]
    }
   ],
   "source": [
    "// Multi-dimensional arrays\n",
    "String[][] x = {{\"00\",\"01\"},{\"10\",\"11\"}};\n",
    "String[][] y = new String[2][2];\n",
    " \n",
    "y[0][0] = \"00\";\n",
    "y[0][1] = \"01\";\n",
    "y[1][0] = \"10\";\n",
    "y[1][1] = \"11\";\n",
    " \n",
    "System.out.print(x[0][0] + x[1][1]); // \"0011\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "Hello World"
     ]
    }
   ],
   "source": [
    "int[] x = new int[3];\n",
    "int size = x.length; // 3\n",
    "\n",
    "// ArrayList class\n",
    "java.util.ArrayList a = new java.util.ArrayList();\n",
    "\n",
    "a.add(\"Hi\");       // add an element\n",
    "a.set(0, \"Hello\"); // change first element\n",
    "a.remove(0);       // remove first element\n",
    "System.out.println(a.size());\n",
    "\n",
    "a.add(\"Hello World\");\n",
    "String s = (String)a.get(0); // Hello World\n",
    "\n",
    "System.out.print(s);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "int[][] a = { {1, 2, 3}, {4, 5} };\n",
    "int x = a[1][0];  // 4\n",
    "// [[1, 2, 3], [4, 5]]\n",
    "Arrays.deepToString(matrix);\n",
    "for (int i = 0; i < a.length; ++i) {\n",
    "  for(int j = 0; j < a[i].length; ++j) {\n",
    "    System.out.println(a[i][j]);\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[a, b, c]"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "char[] chars = {'b', 'a', 'c'};\n",
    "Arrays.sort(chars);\n",
    "// [a, b, c]\n",
    "Arrays.toString(chars);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **07 Conditionals**\n",
    "在Java中，条件判断主要通过if、else if和else语句来实现。 \n",
    "1. if语句：if语句用于测试某个条件是否满足。如果条件满足（即条件表达式的值为true），则执行if后面的代码块。\n",
    "2. if…else语句：if语句后面可以跟else语句。当if语句的条件表达式值为false时，else语句块会被执行。\n",
    "3. if…else if…else语句：if语句后面可以跟多个else if语句，用于检测多种可能的情况。一旦其中一个else if语句检测为true，其他的else if以及else语句都将跳过执行。\n",
    "4. 嵌套的if…else语句：可以在一个if或else if语句中使用另一个if或else if语句。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 = 1\n"
     ]
    }
   ],
   "source": [
    "// If statement\n",
    "int x = 1;\n",
    "\n",
    "if (x == 1) {\n",
    "  System.out.println(x + \" = 1\");\n",
    "}\n",
    "else if (x > 1) {\n",
    "  System.out.println(x + \" > 1\");\n",
    "}\n",
    "else {\n",
    "  System.out.println(x + \" < 1\");\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 = 1\n"
     ]
    }
   ],
   "source": [
    "int x = 1;\n",
    "if (x == 1)\n",
    "  System.out.println(x + \" = 1\");\n",
    "else if (x > 1)\n",
    "  System.out.println(x + \" > 1\");\n",
    "else\n",
    "  System.out.println(x + \" < 1\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "switch语句是一种多分支选择结构，根据一个表达式的值选择不同的代码块执行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 is 1\n"
     ]
    }
   ],
   "source": [
    "int x = 1;\n",
    "// Switch statement\n",
    "switch (x)\n",
    "{\n",
    "  case 0:  System.out.println(x + \" is 0\"); break;\n",
    "  case 1:  System.out.println(x + \" is 1\"); break;\n",
    "  default: System.out.println(x + \" is something else\");\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "apple\n"
     ]
    }
   ],
   "source": [
    "String fruit = \"apple\";\n",
    "switch (fruit)\n",
    "{ \n",
    "  case \"apple\": System.out.println(\"apple\"); break;\n",
    "  default: System.out.println(\"not an apple\");\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "two or three"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = 3;\n",
    "// Switch expression\n",
    "String result;\n",
    "switch (x) \n",
    "{\n",
    "  case 1 -> result = \"one\";\n",
    "  case 2, 3 -> result = \"two or three\";\n",
    "  default -> result = \"many\";\n",
    "} "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "one"
     ]
    }
   ],
   "source": [
    "x = 1;\n",
    "String result = switch (x) \n",
    "{\n",
    "  case 1 -> \"one\";\n",
    "  case 2, 3 -> \"two or three\";\n",
    "  default -> {\n",
    "    if (x == 4) yield \"four\";\n",
    "    else yield \"many\";\n",
    "  }\n",
    "};\n",
    "System.out.print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.0"
     ]
    }
   ],
   "source": [
    "double x = 0.2;\n",
    "// Ternary operator (?:)\n",
    "x = (x < 0.5) ? 0 : 1;\n",
    "System.out.print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **08 Loops**\n",
    "\n",
    "在Java中，主要有以下几种循环语句：\n",
    "1. while循环：while循环会在条件表达式为true时反复执行循环体。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "01234"
     ]
    }
   ],
   "source": [
    "int i = 0;\n",
    "while (i < 5) { \n",
    "  System.out.print(i++); \n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. do…while循环：do...while循环和while循环类似，不同的是，do...while循环至少会执行一次循环体。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "01234"
     ]
    }
   ],
   "source": [
    "int i = 0;\n",
    "do {\n",
    "  System.out.print(i++);\n",
    "} while (i < 5); // \"01234\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. for循环：for循环的执行次数在执行前就确定。语法格式如下：\n",
    "```java\n",
    "    for (初始化变量; 布尔表达式; 更新变量) { // 代码语句 }\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "01234"
     ]
    }
   ],
   "source": [
    "for (int i = 0; i < 5; i++) {\n",
    "    System.out.print(i); // \"01234\"\n",
    "  }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "00000"
     ]
    }
   ],
   "source": [
    "for (int k = 0, m = 0; k < 5; k++, m--) {\n",
    "    System.out.print(k + m); // \"00000\"\n",
    "  }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "00000"
     ]
    }
   ],
   "source": [
    "for (int k = 0, m = 0; k < 5;) {\n",
    "    System.out.print(k + m); // \"00000\" \n",
    "    k++; m--;\n",
    "  } "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4. 增强型for循环：增强型for循环主要用于数组和集合的遍历。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123"
     ]
    }
   ],
   "source": [
    "int[] array = { 1,2,3 };\n",
    "for (int element : array) {\n",
    "  System.out.print(element); // \"123\"\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0124"
     ]
    }
   ],
   "source": [
    "// Break and continue\n",
    "for (int i = 0; i < 10; i++)\n",
    "{\n",
    "  if (i == 5) break; // end loop\n",
    "  if (i == 3) continue; // start next iteration\n",
    "  System.out.print(i); // \"0124\"\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "myLoop: for (int i = 0; i < 10; i++)\n",
    "{ \n",
    "  for (int j = 0; j < 10; j++)\n",
    "  { \n",
    "    break myLoop; // end outer for loop\n",
    "  } \n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Labeled block\n",
    "validation:\n",
    "{\n",
    "  if(true)\n",
    "    break validation;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **09 Methods**\n",
    "\n",
    "在Java中，方法是一段只有在被调用时才会执行的代码块。我们可以将数据（称为参数）传递到方法中。方法用于执行特定的操作，也被称为函数。 \n",
    "\n",
    "定义方法： 方法必须在类中声明。它以方法的名称定义，后面跟着括号()。\n",
    "\n",
    "Java提供了一些预定义的方法，例如System.out.println()，但我们也可以创建自己的方法来执行特定的操作。\n",
    "\n",
    "在Java中，方法可以有参数或没有参数，可以有返回值或没有返回值。下面是这四种情况的详细解释和示例： \n",
    "1. 有参数的方法：在Java中，你可以在方法的括号中定义参数。参数是在调用方法时传递给方法的值。\n",
    "2. 没有参数的方法：如果一个方法不需要任何参数，你可以在方法的括号中什么都不写。\n",
    "3. 有返回值的方法：在Java中，方法可以返回一个值。为了让方法返回一个值，你需要使用return关键字，后面跟着要返回的值。\n",
    "4. 没有返回值的方法：如果一个方法不需要返回任何值，你可以使用void关键字作为方法的返回类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello\n",
      "Hello"
     ]
    }
   ],
   "source": [
    "class MyApp\n",
    "{\n",
    "  void myPrint()\n",
    "  {\n",
    "    System.out.print(\"Hello\");\n",
    "  }\n",
    "\n",
    "  void myPrint(String s)\n",
    "  {\n",
    "    System.out.print(s);\n",
    "  }\n",
    "\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    MyApp m = new MyApp();\n",
    "    m.myPrint();        // \"Hello\"\n",
    "    System.out.println();\n",
    "    m.myPrint(\"Hello\"); // \"Hello\"\n",
    "  }\n",
    "}\n",
    "\n",
    "MyApp.main(null);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello"
     ]
    }
   ],
   "source": [
    "class MyApp\n",
    "{\n",
    "  String getString()\n",
    "  {\n",
    "    return \"Hello\";\n",
    "  }\n",
    "\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    MyApp m = new MyApp();\n",
    "    System.out.print( m.getString() ); // \"Hello\"\n",
    "  }\n",
    "}\n",
    "MyApp.main(null);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "void myPrint(String s)\n",
    "{\n",
    "  if (s == \"\") { return; } // skip if string is empty\n",
    "  System.out.println(s);\n",
    "}\n",
    "\n",
    "// Passing arguments\n",
    "public class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    MyApp m = new MyApp();\n",
    "    int x = 0;                // value data type\n",
    "    m.set(x);                 // value is passed\n",
    "    System.out.println(x);    // \"0\"\n",
    "\n",
    "    int[] y = {0};            // reference data type\n",
    "    m.set(y);                 // address is passed\n",
    "    System.out.println(y[0]); // \"10\"\n",
    "  }\n",
    "\n",
    "  void set(int a) { a = 10; }\n",
    "  void set(int[] a) { a[0] = 10; }\n",
    "}\n",
    "\n",
    "MyApp.main(null);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 方法中参数的传递\n",
    "在Java中，方法参数总是通过值传递。然而，所有的对象（包括数组，即使是基本类型的数组）都是通过指针引用的，这允许通过其方法（或对于数组，通过数组访问）修改对象，而这个指针是通过值传递的。 \n",
    "1. 值传递： 当参数通过值传递时，调用者和被调用的方法在两个不同的变量上操作，这两个变量是彼此的副本。对一个变量的任何更改都不会修改另一个变量。这意味着在调用方法时，传递给被调用方法的参数将是原始参数的副本。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a的值: 10, b的值: 20\n"
     ]
    }
   ],
   "source": [
    "class CallByValue {\n",
    "\tpublic static void example(int x, int y) {\n",
    "\tx++;\n",
    "\ty++;\n",
    "\t}\n",
    "}\n",
    "\n",
    "int a = 10;\t\n",
    "int b = 20;\n",
    "CallByValue.example(a, b); \n",
    "System.out.println(\"a的值: \" + a + \", b的值: \" + b);\n",
    "// 输出结果:\n",
    "// a的值: 10,b的值: 20"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 引用传递：当参数通过引用传递时，对形式参数的任何更改都会反映到调用环境中的实际参数。因为形式参数接收到的是实际数据的引用（或指针）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a的值:10, b的值:20\n",
      "a的值:20, b的值:40\n"
     ]
    }
   ],
   "source": [
    "class CallByReference { \n",
    "\tint a, b;\n",
    "\tCallByReference(int x, int y) {\n",
    "\t\ta = x;\n",
    "\t\tb = y;\n",
    "\t}\n",
    "\n",
    "\tvoid changeValue(CallByReference obj) {\n",
    "\t\tobj.a += 10;\n",
    "\t\tobj.b += 20;\n",
    "\t}\n",
    "}\n",
    "\n",
    "CallByReference obj = new CallByReference(10, 20);\n",
    "System.out.println(\"a的值:\" + obj.a + \", b的值:\" + obj.b);\n",
    "obj.changeValue(obj); \n",
    "System.out.println(\"a的值:\" + obj.a + \", b的值:\" + obj.b);\n",
    "\n",
    "// 输出结果:\n",
    "// a的值:10, b的值: 20\n",
    "// a的值:20, b的值: 40\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **10 Class**\n",
    "\n",
    "Java里面的类由关键字class定义,\n",
    "- 类中的元素称为：成员属性。\n",
    "- 类中的函数称为：成员方法\n",
    "\n",
    "对象的创建和使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Area = 50\n"
     ]
    }
   ],
   "source": [
    "class MyRectangle\n",
    "{\n",
    "  //成员属性 实例变量 \n",
    "  public int x = 10, y = 20;\n",
    "  //成员方法\n",
    "  public int getArea() { return x * y; }\n",
    "  // 构造方法\n",
    "  public MyRectangle()      { this(10,20);  }\n",
    "  public MyRectangle(int a) { this(a,a);    }\n",
    "  \n",
    "  public MyRectangle(int x, int y)\n",
    "  {\n",
    "    this.x = x; \n",
    "    this.y = y;\n",
    "  }\n",
    "}\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    " {\n",
    "    // Create an object of MyRectangle\n",
    "    MyRectangle r = new MyRectangle();\n",
    "    r.x = 10;\n",
    "    r.y = 5;\n",
    "    int z = r.getArea(); // 50 (5*10)\n",
    "    System.out.println(\"Area = \"+z);\n",
    "  }\n",
    "}\n",
    "MyApp.main(null)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造方法\n",
    "- 构造方法没有返回值，也不需要指定为void。\n",
    "- 构造方法的名称一定和类名称一样。\n",
    "- 构造方法只能由new运算符调用。\n",
    "- 当没有指定构造方法时，编译器会为类自动添加形如 类名() {} 的构造方法，成员变量的取值为各种类型的默认值\n",
    "- 当我们自行编写一个构造方法之后，Java在编译时就不再会帮加上前面提到的那个默认的无参构造方法。\n",
    "- 使用不同数量、不同类型的参数对类初始化会拥有多个构造方法\n",
    "\n",
    "## 成员与域\n",
    "- 类中的成员变量——称为字段（亦即 “域”）\n",
    "- 一个方法或代码块中的变量——称为局部变量（亦即 “本地变量”）\n",
    "- 在函数（方法）声明中的变量——称为参数\n",
    "- 成员变量, 包含：类变量（也称静态变量、静态域）和实例变量（也称实例域、非静态域）。\n",
    "    - 类变量\n",
    "        由static修饰，每个类的实例共享一个类变量，它位于内存中的一个固定位置。任何对象都可以改变类变量的值，但是也可以在不创建类的实例的情况下操作类变量。\n",
    "    - 实例变量\n",
    "        当一个类实例化多个对象时，它们都有自己独立的实例变量副本。每个对象都有自己的这些变量的值，存储在不同的内存位置。\n",
    "\n",
    "### 静态类型\n",
    "- 用static关键字可以声明类变量(静态变量)和类方法(静态方法)。\n",
    "- 类变量为该类的所有对象共享。\n",
    "- 类变量可通过类名直接访问，也可以通过该类的对象访问。\n",
    "- 类变量在类加载时，就分配了内存空间。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 访问修饰符\n",
    "<!--rehype:wrap-class=col-span-2-->\n",
    "\n",
    "| 修饰符    | Class | Package | Subclass | World |\n",
    "|-------------|-------|---------|----------|-------|\n",
    "| public      | Y     | Y       | Y        | Y     |\n",
    "| protected   | Y     | Y       | Y        | _N_   |\n",
    "| no modifier | Y     | Y       | _N_      | _N_   |\n",
    "| private     | Y     | _N_     | _N_      | _N_   |\n",
    "<!--rehype:className=show-header-->\n",
    "\n",
    "### 修饰符使用说明：\n",
    "- 只有公用的程序中的某些方法，才会使用public修饰符。\n",
    "- 某个成员对于大部分程序来说不太会使用到，但是对于别的package中继承的子类中会使用到，则使用protected修饰符。\n",
    "- 如果只想让同package中的类使用的方法或是属性，则使用(default)修饰符。\n",
    "- 对于只是自己类内部所使用的属性或方法，则使用private修饰符来隐藏它们。\n",
    "- 不确定该用何种修饰符，最好设定为(default)\n",
    "- 对于class的权限修饰符只可以用public和default。\n",
    "   - public类，可以在任意地方被访问。\n",
    "   - default类，只可以被同一个包内的类访问。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Default values\n",
    "public class MyApp\n",
    "{ \n",
    "  int x; // field is assigned default value 0\n",
    " \n",
    "  int dummy() { \n",
    "    int x; // local variable must be assigned if used\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Garbage collector\n",
    "public class MyApp\n",
    "{ \n",
    "  public static void main(String[] args)\n",
    "  { \n",
    "    MyApp a = new MyApp();\n",
    "\n",
    "    // Make object available for garbage collection\n",
    "    a = null;\n",
    "  } \n",
    "} "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **11 Static**\n",
    "\n",
    "static 修饰符。在Java中，被static修饰的方法和不被static修饰的方法有一些重要的区别。 \n",
    "1. 关联性： \n",
    "static方法与类本身关联，而非static方法（也称为实例方法）与类的每个对象实例关联。 \n",
    "static方法可以直接使用类名调用，而无需创建类的实例。而非static方法需要通过类的对象实例来调用。 \n",
    "2. 内存分配： \n",
    "static方法在类加载时只分配一次内存，所有类的实例共享static方法。 \n",
    "非static方法对于类的每个实例都单独分配内存，每个对象都有其自己的非static方法副本。 \n",
    "3. 访问权限： \n",
    "static方法只能访问类的static成员，不能直接访问类的非static成员。 \n",
    "非static方法可以访问类的static成员和非static成员"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "class MyCircle\n",
    "{\n",
    "  float r = 10;            // instance field\n",
    "  static float pi = 3.14F; // static/class field\n",
    " \n",
    "  // Instance method\n",
    "  float getArea() { return newArea(r); }\n",
    " \n",
    "  // Static/class method\n",
    "  static float newArea(float a) { return pi*a*a; }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Accessing static members\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    float f = MyCircle.pi;\n",
    "    MyCircle c = new MyCircle();\n",
    "    float g = c.r;\n",
    "    double pi = Math.PI;\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Static fields\n",
    "class MyCircle\n",
    "{\n",
    "  static void foo() { count++; }\n",
    "  static int count = 0;\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Static initialization blocks\n",
    "class MyClass\n",
    "{\n",
    "  static int[] array = new int[5];\n",
    "\n",
    "  // Static initialization block\n",
    "  static\n",
    "  { \n",
    "    int i = 0;\n",
    "    for(int element : array)\n",
    "      element = i++;\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Instance initialization blocks\n",
    "class MyClass\n",
    "{\n",
    "  int[] array = new int[5];\n",
    "\n",
    "  // Initialization block\n",
    "  { \n",
    "    int i = 0;\n",
    "    for(int element : array) element = i++;\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **12 Inheritance**\n",
    "\n",
    "Java中使用extends关键字实现类的继承机制。\n",
    "- Java只支持单继承，不允许多继承。\n",
    "- 注意：修饰符为private的属性和方法不会被继承。\n",
    "- 注意：构造方法也不会被继承。\n",
    "- 根类：java.lang.Object类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Superclass (parent class)\n",
    "class Fruit\n",
    "{\n",
    "  public String flavor;\n",
    "}\n",
    " \n",
    "// Subclass (child class)\n",
    "class Apple extends Fruit\n",
    "{\n",
    "  public String variety;\n",
    "}\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    // Upcast and downcast\n",
    "    Apple a = new Apple();\n",
    "    Fruit f = a;\n",
    "    f.flavor = \"Sweet\";\n",
    "    Apple b = (Apple)f;\n",
    "    Apple c = (f instanceof Apple) ? (Apple)f : null;\n",
    "  }\n",
    "}\n",
    "MyApp.main(null);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 对象状态的确定（instanceOf）\n",
    "instanceof是Java的一个二元运算符，作用是测试它左边的对象是否是它右边的类的实例，返回boolean类型的数据。  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Instance of operator\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    Apple f = new Apple();\n",
    "    if (f instanceof Apple)\n",
    "    {\n",
    "      Apple myApple = (Apple)f;\n",
    "      // use myApple here\n",
    "    }\n",
    "    Fruit f2 = new Apple();\n",
    "    if (f2 instanceof Apple myApple)\n",
    "    {\n",
    "      // use myApple here\n",
    "    }\n",
    "  }\n",
    "}\n",
    "MyApp.main(null);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Pattern matching switch\n",
    "public class MyApp \n",
    "{\n",
    "  public static void main(String[] args) \n",
    "  {\n",
    "    Object o = 5L; // L suffix means Long type\n",
    "    String myType = switch(o) \n",
    "    {\n",
    "      case null      -> \"null\";\n",
    "      case Integer i -> \"integer is \" + i;\n",
    "      case Long l    -> \"long is \" + l;\n",
    "      default        -> o.toString();\n",
    "    };\n",
    "    System.out.println(myType); // \"long is 5\"\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Restricting inheritance\n",
    "// Can be inherited by any class\n",
    "non-sealed class Lemon extends Fruit {}\n",
    "\n",
    "// Can be inherited only by RedDelicious class\n",
    "sealed class Apple extends Fruit permits RedDelicious {}\n",
    "\n",
    "// Cannot be inherited\n",
    "final class Orange extends Fruit {}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 继承中的构造方法\n",
    "- 子类的构造过程中必须调用其父类的构造方法。\n",
    "- 调用方法：显式和隐式\n",
    "     1. 显式：子类可以在自己的构造方法super(参数列表)调用父类的构造方法。\n",
    "      注：如果调用super(参数列表)，则必须写在子类构造方法的第一行。\n",
    "     2. 隐式：如果子类的构造方法中没有显式地调用父类的构造方法，则系统默认先调用父类无参的构造方法。\n",
    "- 如果子类构造方法中既没显式调用父类构造方法，而父类中又没有无参的构造方法，则编译出错。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **13 Overriding**\n",
    "\n",
    "多态\n",
    "概念：是指在执行期间（而非编译期间）判断所引用对象的实际类型，根据其实际的类型调用其方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "50\n",
      "50\n",
      "50\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100\n"
     ]
    }
   ],
   "source": [
    "class Rectangle\n",
    "{\n",
    "  public int w = 10, h = 10;\n",
    "\n",
    "  public int getArea() { \n",
    "    return w * h; \n",
    "  }\n",
    "\n",
    "  public static int newArea(int a, int b) {\n",
    "    return a * b;\n",
    "  }\n",
    "}\n",
    " \n",
    "class Triangle extends Rectangle\n",
    "{\n",
    "  @Override public int getArea() {\n",
    "    return w * h / 2;\n",
    "  }\n",
    "\n",
    "  public static int newArea(int a, int b) {\n",
    "    return a * b / 2;\n",
    "  }\n",
    "}\n",
    "\n",
    "Triangle o1 = new Triangle();\n",
    "System.out.println(o1.getArea()); // (50) calls Triangle's version\n",
    "\n",
    "Rectangle o2 = new Triangle();\n",
    "System.out.println(o2.getArea()); // (50) calls Triangle's version\n",
    "\n",
    "Triangle o3 = new Triangle();\n",
    "System.out.println(o3.newArea(10,10)); // (50) calls Triangle's version\n",
    "\n",
    "Rectangle r = o3;\n",
    "System.out.println(r.newArea(10,10)); // (100) calls Rectangle's version"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "猫叫声…\n",
      "狗叫声…\n"
     ]
    }
   ],
   "source": [
    "class Animal {\n",
    "    public String name;\n",
    "    Animal(String name) {    this.name = name;   }\n",
    "    public void enjoy() {System.out.println(\"叫声。。。\"); }\n",
    "}\n",
    "  \n",
    "class Cat extends Animal {\n",
    "    public String eyesColor;\n",
    "    Cat(String n, String c) {\n",
    "     super(n);  eyesColor = c;\n",
    "    }\n",
    "    public void enjoy() { System.out.println(\"猫叫声…\"); }\n",
    "}\n",
    "\n",
    "class Dog extends Animal {\n",
    "    public String furColor;\n",
    "    Dog(String n, String c) {\n",
    "      super(n);  furColor = c;\n",
    "    }\n",
    "   public void enjoy() { System.out.println(\"狗叫声…\"); }\n",
    "}\n",
    "\n",
    "class Lady {\n",
    "    private String name;\n",
    "    private Animal pet;\n",
    "    Lady(String name, Animal pet) {\n",
    "      this.name = name;  this.pet = pet;\n",
    "    }\n",
    "     public void myPetEnjoy() {  pet.enjoy();  }\n",
    "  }\n",
    "\n",
    "Cat c = new Cat(\"cat_name\", \"blue\");\n",
    "Dog d = new Dog(\"dog_name\", \"black\");  \n",
    "Lady l1 = new Lady(\"l1\", c);\n",
    "Lady l2 = new Lady(\"l2\", d);\n",
    "l1.myPetEnjoy();\n",
    "l2.myPetEnjoy();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Hiding fields\n",
    "class Rectangle \n",
    "{\n",
    "  public int w = 10, h = 10;\n",
    "}\n",
    "\n",
    "class Triangle extends Rectangle \n",
    "{\n",
    "  public int w = 5, h = 5; // hide inherited fields\n",
    "}\n",
    "\n",
    "public class MyApp \n",
    "{\n",
    "  public static void main(String args[]) {\n",
    "    Triangle t = new Triangle();\n",
    "    Rectangle r = t;\n",
    "    System.out.println(t.w); // \"5\"\n",
    "    System.out.println(r.w); // \"10\"\n",
    "  }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Preventing method inheritance\n",
    "public final int getArea() { return w * h; }\n",
    " \n",
    "// Accessing redefined members\n",
    "class Triangle extends Rectangle\n",
    "{ \n",
    "  @Override public int getArea() { \n",
    "    return super.getArea() / 2;\n",
    "  }\n",
    "}\n",
    "\n",
    "// Calling parent constructor\n",
    "public Triangle(int a, int b) { super(a,b); }\n",
    "public Triangle() { super(); }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **14 Packages and Import**\n",
    "\n",
    "在Java中，包是一种用于封装一组相关类型（如类、接口、枚举和注解）的机制。包的主要作用是防止命名冲突，使类的搜索/定位和使用更加容易，以及提供受控访问。\n",
    "Java中的常用包包括：\n",
    "- java.lang：包含基本类，如String，Math，System等。\n",
    "- java.util：包含实用工具类，如ArrayList，HashMap，Date等。\n",
    "- java.io：包含输入/输出操作的类。\n",
    "- java.net：包含网络操作的类。\n",
    "- java.sql：包含Java数据库连接（JDBC）类。\n",
    "\n",
    "要在Java中导入包，可以使用import关键字。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Import specific class 只导入java.util包中的ArrayList类 \n",
    "import java.util.ArrayList;\n",
    "\n",
    "ArrayList m;\n",
    "\n",
    "// Import package 导入整个java.util包\n",
    "import java.util.*;\n",
    "\n",
    "// Import static 导入java.lang.Math包中的所有静态成员\n",
    "import static java.lang.Math.*;\n",
    "\n",
    "double pi = PI; // Math.PI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **15 Modules**\n",
    "\n",
    "在Java中，模块是一种用于封装一组相关类型（如类、接口、枚举和注解）的机制。模块系统为我们的程序提供了额外的封装层，因为我们可以指定哪个包可以被模块使用，以及哪些模块可以访问它们。 \n",
    "\n",
    "Java 9引入了模块系统，这是其主要特性之一。模块系统的主要目标是将Java包和代码收集到一个称为模块的单元中。这样做的原因是，当我们想要使用Java创建模块化应用程序时，Java 9之前的版本没有这样的系统，这就导致了应用程序的大小增加。为了避免这种情况，Java 9将JDK分割成了一组模块，这样我们就可以使用所需的模块来开发我们的应用程序。\n",
    "```java\n",
    "module $NAME {\n",
    "        // 对每个依赖项: \n",
    "        requires $MODULE; \n",
    "        // 对每个API包: \n",
    "        exports $PACKAGE;\n",
    "        // 对每个用于反射的包:\n",
    "        opens $PACKAGE;\n",
    "        // 对每个使用的服务:\n",
    "        uses $TYPE;\n",
    "        // 对每个提供的服务:\n",
    "        provides $TYPE with $CLASS;\n",
    "}\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// util.MyClass.java\n",
    "package util;\n",
    "public class MyClass {\n",
    "  public static void sayHi() {\n",
    "    System.out.println(\"Hello Module\");\n",
    "  }\n",
    "} \n",
    "\n",
    "// module-info.java - firstmodule\n",
    "module firstmodule {\n",
    "  exports firstmodule.util; // make package visible\n",
    "}\n",
    "\n",
    "// module-info.java - secondmodule\n",
    "module secondmodule {\n",
    "  requires firstmodule; // import module\n",
    "}\n",
    "\n",
    "// app.MyApp.java\n",
    "package app;\n",
    "public class MyApp {\n",
    "  public static void main(String[] args) {\n",
    "    util.MyClass.sayHi(); // \"Hello Module\"\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **16 Access Levels** \n",
    "\n",
    "在Java中，访问级别是通过访问修饰符来控制的。访问修饰符用于指定类、构造函数、变量、方法或数据成员的作用域。Java有四种访问修饰符：\n",
    "- public：公有修饰符的访问级别是最广的，它可以在任何地方访问。它可以在类内部、类外部、包内部，甚至包外部访问。\n",
    "- private：私有修饰符的访问级别仅限于类内部，不能在类外部访问。\n",
    "- protected：受保护的修饰符的访问级别在包内部和通过子类在包外部。如果你不创建子类，它不能在包外部访问。\n",
    "- default：默认修饰符的访问级别仅限于包内部。它不能在包外部访问。如果你不指定任何访问级别，它将默认为default。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Private access\n",
    "package mypackage;\n",
    "public class MyApp\n",
    "{\n",
    "  public    int myPublic;   // unrestricted access\n",
    "  protected int myProtected;// package or subclass access\n",
    "            int myPackage;  // package access\n",
    "  private   int myPrivate;  // class access\n",
    " \n",
    "  void test()\n",
    "  {\n",
    "    myPublic    = 0; // allowed\n",
    "    myProtected = 0; // allowed\n",
    "    myPackage   = 0; // allowed\n",
    "    myPrivate   = 0; // allowed\n",
    "  }\n",
    "}\n",
    "\n",
    "// Package-private access\n",
    "class MyClass\n",
    "{\n",
    "  void test(MyApp m)\n",
    "  {\n",
    "    m.myPublic    = 0; // allowed\n",
    "    m.myProtected = 0; // allowed\n",
    "    m.myPackage   = 0; // allowed\n",
    "    m.myPrivate   = 0; // inaccessible\n",
    "  }\n",
    "}\n",
    " \n",
    "// Protected access\n",
    "package newpackage;\n",
    "import mypackage.MyApp;\n",
    " \n",
    "class MyClass extends MyApp\n",
    "{\n",
    "  void test()\n",
    "  {\n",
    "    myPublic    = 0; // allowed\n",
    "    myProtected = 0; // allowed (in subclass)\n",
    "    myPackage   = 0; // inaccessible\n",
    "    myPrivate   = 0; // inaccessible\n",
    "  }\n",
    "}\n",
    "\n",
    "package mypackage;\n",
    "public class MyTest\n",
    "{\n",
    "  void test(MyApp m)\n",
    "  {\n",
    "    m.myPublic    = 0; // allowed\n",
    "    m.myProtected = 0; // allowed (same package)\n",
    "    m.myPackage   = 0; // inaccessible\n",
    "    m.myPrivate   = 0; // inaccessible\n",
    "  }\n",
    "}\n",
    "\n",
    "// Public access\n",
    "package newpackage;\n",
    "class MyClass\n",
    "{\n",
    "  void test(MyApp m)\n",
    "  {\n",
    "    m.myPublic    = 0; // allowed\n",
    "    m.myProtected = 0; // inaccessible\n",
    "    m.myPackage   = 0; // inaccessible\n",
    "    m.myPrivate   = 0; // inaccessible\n",
    "  }\n",
    "}\n",
    "\n",
    "// Accessible only from containing package\n",
    "class PackagePrivateClass {}\n",
    " \n",
    "// Accessible from any package\n",
    "public class PublicClass {}\n",
    " \n",
    "// Nested class access\n",
    "class MyClass\n",
    "{\n",
    "  // Only accessible within MyClass\n",
    "  private class PrivateNestedClass {}\n",
    "}\n",
    "\n",
    "class MyClass\n",
    "{\n",
    "  // Only accessible within containing package\n",
    "  public class PrivateNestedClass {}\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **17 Constants**\n",
    "在Java中，常量是一个在赋值后其值不能改变的变量。Java并不直接支持常量，但我们可以通过使用static和final修饰符来定义常量。\n",
    "- static修饰符用于管理内存，它允许变量在其定义的类的任何实例加载之前就可用。\n",
    "- final修饰符表示变量的值不能改变，它使基本数据类型不可变或不可更改。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    // Local constant\n",
    "    final double PI = 3.14;\n",
    "  }\n",
    "}\n",
    "\n",
    "// Constant fields\n",
    "class MyClass\n",
    "{\n",
    "  final double E;\n",
    "  final double PI;\n",
    "  static final double C;\n",
    "\n",
    "  public MyClass() { E = 2.72; }\n",
    "  { PI = 3.14; }\n",
    "  static { C = 3e8; }\n",
    "}\n",
    "\n",
    "// Compile-time and runtime constants\n",
    "class MyClass\n",
    "{ \n",
    "  // Compile-time constant (static and known at compile-time)\n",
    "  final static double C = 3e8;\n",
    " \n",
    "  // Run-time constant (not static)\n",
    "  final double E = 2.72;\n",
    " \n",
    "  // Run-time constant (not known at compile-time)\n",
    "  final static int RND = (new java.util.Random()).nextInt();\n",
    "}  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **18 Interface**\n",
    "是抽象方法和常量的定义的集合。\n",
    "> 从本质上讲，接口是一种特殊的抽象类，这种抽象类中只包含常量和方法的定义，而没有变量和方法的实现。\n",
    "\n",
    "接口的定义格式：\n",
    "```java\n",
    "[public] interface 接口名 [extends 父接口名列表] {\n",
    "    type NAME = value;\n",
    "    //该常量被实现该接口的多个类共享；\n",
    "    //缺省的具有public, final, static的属性\n",
    "    returntype methodName([paramlist]);\n",
    "   //缺省的具有 public和abstract属性\n",
    "}\n",
    "```\n",
    "\n",
    "特性：\n",
    "- 接口中声明的成员变量默认为public static final的，且也只能是public static final的；\n",
    "- 接口中只能定义为抽象方法，而且这些方法默认为public的，且也只能为public的\n",
    "- 接口可以继承其它接口，并添加新的属性和抽象方法。\n",
    "```java\n",
    "      [public] interface 接口名 [extends 父接口名列表] \n",
    "      { … }\n",
    "```\n",
    "- 接口可以实现多继承。\n",
    "   - 即一个接口可有多个父接口(即接口可实现多继承)，用逗号隔开\n",
    "\n",
    "- 在类的声明中用implements子句来表示一个类使用某个接口。\n",
    "- 多个无关的类可以实现同一个接口。\n",
    "- 一个类可以实现多个无关的接口。\n",
    "\n",
    "定义Java类的语法格式：\n",
    "```java\n",
    "<修饰符> 类名 [extends <父类名>] [implements <接口1> [, <接口2 >]…] {\n",
    "  <类定义体>\n",
    "}\n",
    "```\n",
    "在类体中可以使用接口中定义的常量，而且必须实现接口中定义的所有方法。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "interface MyInterface \n",
    "{\n",
    "  int myMethod(); // method signature\n",
    "\n",
    "  int c = 10; // constant\n",
    "\n",
    "  // Types\n",
    "  class Class {}\n",
    "  interface Interface {}\n",
    "  enum Enum {}\n",
    "}\n",
    "\n",
    "// Functionality interface\n",
    "interface Comparable\n",
    "{\n",
    "  int compare(Object o);\n",
    "}\n",
    "\n",
    "class Circle implements Comparable\n",
    "{\n",
    "  public int r;\n",
    "\n",
    "  public int compare(Object o) {\n",
    "    return r - ( (Circle)o ).r;\n",
    "  }\n",
    "\n",
    "  public static Object largest(Comparable a, Comparable b)\n",
    "  {\n",
    "    return (a.compare(b) > 0) ? a : b;\n",
    "  }\n",
    "}\n",
    "\n",
    "// Class interface\n",
    "interface MyInterface\n",
    "{\n",
    "  void exposed();\n",
    "}\n",
    " \n",
    "class MyClass implements MyInterface\n",
    "{\n",
    "  @Override\n",
    "  public void exposed() {}\n",
    "  public void hidden() {}\n",
    "}\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    MyInterface i = new MyClass();\n",
    "  }\n",
    "}\n",
    "\n",
    "// Interface classes\n",
    "interface MyInterface\n",
    "{\n",
    "  class HelperClass {\n",
    "    public static void helperMethod() {}\n",
    "  }\n",
    "}\n",
    "\n",
    "// Default interface methods\n",
    "interface MyInterface\n",
    "{ \n",
    "  default void defaultMethod() {\n",
    "    System.out.println(\"default\");\n",
    "  } \n",
    "\n",
    "  static void staticMethod() {\n",
    "    System.out.println(\"static\");\n",
    "  }\n",
    "\n",
    "  private static String getString() {\n",
    "    return \"string\";\n",
    "  } \n",
    "\n",
    "  default void printString() {\n",
    "    System.out.println(getString());\n",
    "  }\n",
    "}\n",
    "\n",
    "class MyApp implements MyInterface \n",
    "{\n",
    "  public static void main(String[] args) { \n",
    "    MyInterface i = new MyApp();\n",
    "    i.defaultMethod(); // \"default\"\n",
    "\n",
    "    MyInterface.staticMethod(); // \"static\"\n",
    "  } \n",
    "} "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 接口作为一种引用类型来使用。\n",
    "- 任何实现该接口的类的实例都可以存储在该接口类型的变量中。\n",
    "- 通过这些变量可以访问类所实现的接口中的方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **19 Abstract**\n",
    " 用abstract关键字修饰的类，即抽象类。\n",
    " > 作用：描述概念性的内容，这样可以提高开发效率，更好地统一用户“接口”。\n",
    "\n",
    " 语法格式:\n",
    " ```java\n",
    "     abstract class 抽象类名{ …} \n",
    "     abstract 返回类型 抽象方法([参数表]);\n",
    "```\n",
    " - 抽象类必须被继承，抽象方法必须被重写。\n",
    " - 抽象类不能被实例化；抽象方法只需声明，无需实现。\n",
    " - 抽象类通常包括一个或多个抽象方法，但不是一定包括\n",
    " - 若类中包含了抽象方法，则该类必须被定义为抽象类。\n",
    " - 虽然抽象类不能产生实例对象，但还是需要构造方法的存在！\n",
    " - abstract关键字只能用在类和方法上，而不能用在属性和一般的变量上。\n",
    " \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "abstract class Shape\n",
    "{\n",
    "  public int x = 100, y = 100;\n",
    "  public abstract int getArea();\n",
    "}\n",
    "\n",
    "class Rectangle extends Shape\n",
    "{\n",
    "  @Override public int getArea() \n",
    "  { \n",
    "    return x * y; \n",
    "  }\n",
    "}\n",
    "\n",
    "abstract class Shape\n",
    "{\n",
    "  public int x = 100, y = 100;\n",
    "  public Shape(int a, int b) { \n",
    "    x = a; \n",
    "    y = b; \n",
    "  }\n",
    "}\n",
    "\n",
    "class Rectangle extends Shape\n",
    "{\n",
    "  public Rectangle(int a, int b) { \n",
    "    super(a,b); \n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **20 Enum**\n",
    "\n",
    "在Java中，枚举（enum）是一种特殊的类，它包含一组固定的常量。我们可以使用enum关键字来声明枚举。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "enum Speed\n",
    "{\n",
    "  STOP, SLOW, NORMAL, FAST\n",
    "}\n",
    " \n",
    " \n",
    "enum Speed\n",
    "{\n",
    "  STOP(0), SLOW(5), NORMAL(10), FAST(20);\n",
    "  public int speed;\n",
    "  Speed(int s) { speed = s; }\n",
    "}\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    Speed[] a = Speed.values();\n",
    "    String s = a[0].toString(); // \"STOP\"\n",
    "    Speed b = Speed.valueOf(s); // Speed.STOP\n",
    "  }\n",
    "}\n",
    "\n",
    "public class MyApp \n",
    "{\n",
    "  public static void main(String args[]) {\n",
    "    Speed s = Speed.NORMAL;\n",
    "    // �\n",
    "    switch(s) {\n",
    "      case STOP: break;\n",
    "      case SLOW: break;\n",
    "      case NORMAL: break;\n",
    "      case FAST: break;\n",
    "    }\n",
    "  }\n",
    "}\n",
    "\n",
    "// Enum class\n",
    "enum Speed\n",
    "{\n",
    "  STOP(0), SLOW(5), NORMAL(10), FAST(20);\n",
    "  public int velocity;\n",
    "  private Speed(int s) { velocity = s; }\n",
    "}\n",
    "\n",
    "public class MyApp \n",
    "{\n",
    "  public static void main(String args[]) {\n",
    "    Speed s = Speed.SLOW;\n",
    "    System.out.println(s.velocity); // \"5\"\n",
    "\n",
    "    Speed[] a = Speed.values();\n",
    "    String s1 = a[0].toString(); // \"STOP\"\n",
    "    Speed b = Speed.valueOf(s1); // Speed.STOP\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **21 Exception Handling**\n",
    "\n",
    "在Java中，异常处理是一种强大的机制，用于处理运行时错误，以便可以维护应用程序的正常流程。Java提供了两种不同的选项来处理异常。可以使用try-catch-finally方法来处理所有类型的异常，或者可以使用try-with-resource方法，这种方法允许资源的清理过程更加容易。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "import java.io.*;\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    try {\n",
    "      FileReader file = new FileReader(\"missing.file\");\n",
    "    }\n",
    "    catch(FileNotFoundException e) {\n",
    "      System.out.print(e.getMessage());\n",
    "    }\n",
    "    catch(Exception e) {\n",
    "      System.out.print(e.getMessage());\n",
    "    }\n",
    "  }\n",
    "}\n",
    " \n",
    "// Finally block\n",
    "import java.io.*;\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    FileReader in = null;\n",
    "    try {\n",
    "      in = new FileReader(\"missing.file\");\n",
    "    }\n",
    "    catch(FileNotFoundException e) {\n",
    "      System.out.print(e.getMessage());\n",
    "    }\n",
    "    finally {\n",
    "      if (in != null) {\n",
    "        try { in.close(); }\n",
    "        catch(IOException e) {}\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "}\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    try(FileReader file = new FileReader(\"missing.txt\")) {\n",
    "      // Read file\n",
    "    } \n",
    "    catch(FileNotFoundException e) {\n",
    "      // Handle exception\n",
    "    }\n",
    "\n",
    "    // Final resource\n",
    "    final FileReader file1 = new FileReader(\"file1.txt\");\n",
    "\n",
    "    // Effectively final resource\n",
    "    FileReader file2 = new FileReader(\"file2.txt\");\n",
    "\n",
    "    try(file1; file2) {\n",
    "      // Read files\n",
    "    } \n",
    "    catch(FileNotFoundException e) {\n",
    "      // Handle exception\n",
    "    }\n",
    "  }\n",
    "}\n",
    " \n",
    "// Throwing exceptions\n",
    "static void makeException() throws Throwable\n",
    "{\n",
    "  throw new Throwable(\"My Throwable\");\n",
    "}\n",
    " \n",
    "// Specifying exceptions\n",
    "import java.io.*;\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  static void MakeException()\n",
    "  throws IOException, FileNotFoundException\n",
    "  {\n",
    "    // ...\n",
    "    throw new IOException(\"My IO exception\");\n",
    "    // ...\n",
    "    throw new FileNotFoundException(\"File missing\");\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **22 Boxing and Unboxing**\n",
    "\n",
    "在Java中，装箱（Boxing）和开箱（Unboxing）是Java 5引入的两个重要概念。 \n",
    "- 装箱（Boxing）：将基本数据类型转换为其对应的包装类对象的过程称为装箱。例如，将int类型转换为Integer类的对象就是装箱。 \n",
    "- 开箱（Unboxing）：将包装类对象转换为其对应的基本数据类型的过程称为开箱。例如，将Integer类的对象转换为int类型就是开箱。\n",
    "\n",
    "在Java中进行装箱和开箱时，有一些注意事项：\n",
    "- 性能：装箱和开箱操作需要在运行时进行，这可能会影响性能。如果你在一个循环中频繁地进行装箱和开箱操作，那么这可能会导致性能下降。\n",
    "- 空指针异常：当你试图对一个为null的包装类对象进行开箱操作时，会抛出NullPointerException。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    int iPrimitive = 5;\n",
    "    Integer iWrapper = new Integer(iPrimitive); // boxing\n",
    "    iPrimitive = iWrapper.intValue(); // unboxing\n",
    "\n",
    "    Integer x = new Integer(1000);\n",
    "    Integer y = new Integer(1000);\n",
    "    boolean b = (x == y);    // false\n",
    "            b = x.equals(y); // true\n",
    "\n",
    "    Integer iWrapper2 = iPrimitive; // autoboxing\n",
    "    iPrimitive = iWrapper2;         // autounboxing\n",
    "\n",
    "    Integer iWrapper3 = Integer.valueOf(iPrimitive);\n",
    "    iPrimitive = iWrapper3.intValue();\n",
    "\n",
    "    java.util.ArrayList a = new java.util.ArrayList();\n",
    "    a.add(Integer.valueOf(5)); // boxing\n",
    "    a.add(10);                 // autoboxing\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **23 Generics**\n",
    "\n",
    "泛型类定义的语法如下：\n",
    "```java\n",
    "[访问修饰符] class 类名称 <T>\n",
    "```\n",
    "泛型类的主要作用在于类被实例化后，传入具体的类型参数，对类的成员属性的类型和成员方法的参数类型和返回值类型进行替换。\n",
    "\n",
    "说明：T可以用任何一种引用类型，但是不允许使用基本类型，如int、double、char、boolean等是不允许的。\n",
    "\n",
    "泛型类定义时，可以使用T来定义其成员变量和成员方法的返回值和参数."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Generic class\n",
    "class MyBox<T> { public T box; }\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    MyBox<Integer> iBox  = new MyBox<Integer>();\n",
    "    MyBox<Integer> iBox2 = new MyBox<>();\n",
    "\n",
    "    iBox.box = 5;\n",
    "    Integer i = iBox.box;\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "泛型方法主要用于容器类，Java中任何方法，包括静态的（注意，泛型类不允许在静态环境中使用）和非静态的，均可以用泛型来定义，而且和所在类是否是泛型没有关系。\n",
    "下面是泛型方法的定义\n",
    "```java\n",
    "[public] [static] <T> 返回值类型 方法名(T 参数列表)\n",
    "```\n",
    "\n",
    "使用泛型方法时，至少返回值或参数有一个是泛型定义的，而且应该保持一致，否则可能会受到各种限制，因此，这里建议保持一致。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 2 3 \n",
      "1 2 3 "
     ]
    }
   ],
   "source": [
    "// Generic methods\n",
    "class MyClass\n",
    "{\n",
    "  public static <T> void printArray(T[] array)\n",
    "  {\n",
    "    for (T element : array)\n",
    "      System.out.print(element + \" \");\n",
    "  }\n",
    "}\n",
    "\n",
    "public class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    Integer[] iArray = { 1, 2, 3 };\n",
    "    MyClass.printArray(iArray); // \"1 2 3\"\n",
    "    System.out.println();\n",
    "    MyClass.<Integer>printArray(iArray); // \"1 2 3\" \n",
    "  }\n",
    "}\n",
    "MyApp.main(null)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n"
     ]
    }
   ],
   "source": [
    "public class MyApp\n",
    "{\n",
    "  private String s;\n",
    "  \n",
    "  public <T> MyApp(T t) {\n",
    "    s = t.toString(); // convert to string\n",
    "  }\n",
    "  \n",
    "  public static void main(String[] args) {\n",
    "    MyApp o = new MyApp(10);\n",
    "    System.out.println(o.s); // \"10\"\n",
    "  }\n",
    "}\n",
    "MyApp.main(null)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Generic functionality interface\n",
    "interface IGenericCollection<T>\n",
    "{\n",
    "  void store(T t);\n",
    "}\n",
    " \n",
    "// Non-generic class implementing generic interface\n",
    "class Box implements IGenericCollection<Integer>\n",
    "{\n",
    "  public Integer myBox;\n",
    "  public void store(Integer i) { myBox = i; }\n",
    "}\n",
    "\n",
    "// Generic class implementing generic interface\n",
    "class GenericBox<T> implements IGenericCollection<T>\n",
    "{\n",
    "  public T myBox;\n",
    "  public void store(T t) { myBox = t; }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Generic variable usages\n",
    "class MyClass<T>\n",
    "{\n",
    "  public void myMethod(Object o)\n",
    "  {\n",
    "    T t1;                            // allowed\n",
    "    t1 = null;                       // allowed\n",
    "    System.out.print(t1.toString()); // allowed\n",
    "    if (o instanceof T) {}           // invalid\n",
    "    T t2 = new T();                  // invalid\n",
    "  }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Bounded type parameters\n",
    "// T must be or inherit from superclass A\n",
    "class B<T extends A> {}\n",
    "class A {}\n",
    "\n",
    "// T must be or implement interface I\n",
    "class C<T extends I> {}\n",
    "interface I {}\n",
    "\n",
    "class D<T extends A & I> {}\n",
    "\n",
    "class E<T extends A & I, U extends A & I> {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "class Fruit\n",
    "{\n",
    "  public String name;\n",
    "}\n",
    " \n",
    "class FruitBox<T extends Fruit>\n",
    "{\n",
    "  private T box;\n",
    "  public void FruitBox(T t) { box = t; }\n",
    "  public String getFruitName()\n",
    "  {\n",
    "    // Use of Fruit member allowed since T extends Fruit\n",
    "    return box.name;\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "// Generics and Object\n",
    "import java.util.ArrayList;\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    // Object ArrayList\n",
    "    ArrayList a = new ArrayList();\n",
    "    a.add(\"Hello World\");\n",
    "\n",
    "    Integer b = (Integer)a.get(0); // run-time error\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.ArrayList;\n",
    "\n",
    "class MyApp\n",
    "{\n",
    "  public static void main(String[] args)\n",
    "  {\n",
    "    // Generic ArrayList (recommended)\n",
    "    ArrayList<String> a = new ArrayList<String>();\n",
    "    a.add(\"Hello World\");\n",
    "\n",
    "    Integer b = (Integer)a.get(0); // compile-time error\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 容器\n",
    "### List\n",
    "Java中的List接口用于存储有序的对象集合。它是Collection接口的子接口。List接口提供了各种方法来插入、访问和删除元素。List接口的实现类包括ArrayList、LinkedList、Stack和Vector。其中，ArrayList和LinkedList在Java编程中被广泛使用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n",
      "1\n",
      "[2, 3]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 20, 3]\n",
      "[2, 12, 3]\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "// 创建一个新的List\n",
    "List<Integer> list = new ArrayList<Integer>();\n",
    "\n",
    "// 添加元素到List\n",
    "list.add(1);\n",
    "list.add(2);\n",
    "list.add(3);\n",
    "\n",
    "System.out.println(list); // 打印List\n",
    "\n",
    "// 访问List中的元素\n",
    "int firstElement = list.get(0);\n",
    "System.out.println(firstElement); // 打印第一个元素\n",
    "\n",
    "// 删除List中的元素\n",
    "list.remove(0);\n",
    "System.out.println(list); //\t打印List\n",
    "\n",
    "// 在特定位置添加元素\n",
    "list.add(1, 20);\n",
    "System.out.println(list); // TEPList\n",
    "\n",
    "// 更新List中的元素\n",
    "list.set(1, 12);\n",
    "System.out.println(list); // 打印List\n",
    "\n",
    "// 搜索List中的元素\n",
    "int index = list.indexOf(3);\n",
    "System.out.println(index); //打印元素的索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "2458"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "45\n",
      "45"
     ]
    }
   ],
   "source": [
    "List<Integer> nums = new ArrayList<>();\n",
    "// 添加\n",
    "nums.add(2);\n",
    "nums.add(4);\n",
    "nums.add(5);\n",
    "nums.add(8);\n",
    "// 检索\n",
    "System.out.println(nums.get(0));\n",
    "// 为循环迭代编制索引\n",
    "for (int i = 0; i < nums.size(); i++) {\n",
    "    System.out.print(nums.get(i));\n",
    "}\n",
    "\n",
    "nums.remove(nums.size() - 1);\n",
    "nums.remove(0); // 非常慢\n",
    "for (Integer value : nums) {\n",
    "    System.out.print(value);\n",
    "}\n",
    "\n",
    "System.out.println();\n",
    "// lambda 打印元素\n",
    "nums.forEach(e -> System.out.print(e.toString()));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set容器\n",
    "Java中的Set接口用于存储无序的对象集合，其中不允许存储重复的值。它是Collection接口的子接口。Set接口提供了一种实现数学集合的方式。Set接口包含从Collection接口继承的方法，并添加了一个特性，即限制插入重复元素。Set接口的实现类包括HashSet、LinkedHashSet、TreeSet等。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n",
      "true\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3]\n"
     ]
    }
   ],
   "source": [
    "// 创建一个新的Set\n",
    "Set<Integer> set = new HashSet<Integer>();\n",
    "\n",
    "// 添加元素到Set\n",
    "set.add(1);\n",
    "set.add(2);\n",
    "set.add(3);\n",
    "\n",
    "System.out.println(set); // 打印Set\n",
    "\n",
    "// 搜索Set中的元素\n",
    "boolean contains_Two = set.contains(2);\n",
    "System.out.println(contains_Two); // 打印搜素结果\n",
    "\n",
    "// 删除Set中的元素\n",
    "set.remove(1);\n",
    "System.out.println(set); // 打印Set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Empty!\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Contains cat\n",
      "mouse\n",
      "snake\n",
      "bear\n",
      "dog\n",
      "\n",
      "mouse\n",
      "snake\n",
      "bear\n",
      "dog\n"
     ]
    }
   ],
   "source": [
    "Set<String> set = new HashSet<>();\n",
    "if (set.isEmpty()) {\n",
    "    System.out.println(\"Empty!\");\n",
    "}\n",
    "set.add(\"dog\");\n",
    "set.add(\"cat\");\n",
    "set.add(\"mouse\");\n",
    "set.add(\"snake\");\n",
    "set.add(\"bear\");\n",
    "if (set.contains(\"cat\")) {\n",
    "    System.out.println(\"Contains cat\");\n",
    "}\n",
    "set.remove(\"cat\");\n",
    "for (String element : set) {\n",
    "    System.out.println(element);\n",
    "}\n",
    "System.out.println();\n",
    "set.forEach(e -> System.out.println(e.toString()));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List 和 Set容器的区别\n",
    "\n",
    "Java 中的 List 和 Set 容器有以下主要区别： \n",
    "1. 顺序：List 是有序的集合，它按照元素插入的顺序保存元素。而 Set 是无序的集合，它不保证元素的存储顺序。 \n",
    "2. 重复元素：List 允许存储重复的元素，而 Set 不允许存储重复的元素。 \n",
    "3. 位置访问：List 允许通过索引位置访问元素，而 Set 不允许这样做。 \n",
    "4. 空元素：List 可以存储多个空元素，而 Set 只能存储一个空元素。 \n",
    "5. 实现类：List 的实现类包括 ArrayList、LinkedList、Vector、Stack 等，而 Set 的实现类包括 HashSet、LinkedHashSet 等。\n",
    "\n",
    "在这个例子中，可以看到 List 允许重复的元素（“Apple”）和多个空元素，而 Set 不允许重复的元素，只能有一个空元素。此外，Set 的输出顺序与插入顺序不同，这是因为 Set 是无序的集合。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "List: [Apple, Banana, Apple, null, null]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Set:[null, Apple, Banana]\n"
     ]
    }
   ],
   "source": [
    "List<String> list = new ArrayList<>();\n",
    "list.add(\"Apple\");\n",
    "list.add(\"Banana\");\n",
    "list.add(\"Apple\");\n",
    "list.add(null);\n",
    "list.add(null);\n",
    "System.out.println(\"List: \"+ list);\n",
    "\n",
    "//创建 Set\n",
    "Set<String> set = new HashSet<>();\n",
    "set.add(\"Apple\");\n",
    "set.add(\"Banana\");\n",
    "set.add(\"Apple\");\n",
    "set.add(null);\n",
    "set.add(null);\n",
    "System.out.println(\"Set:\"+ set); "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Map容器\n",
    "Map接口不是Collection接口的子类型，因此它与其他集合类型的行为略有不同。Map的每个元素是包括一个键值对，可以通过键去访问其值。Map不允许重复的键，但可以有重复的值。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{One=1, Two=2, Three=3}\n",
      "2\n",
      "true\n",
      "{One=1, Three=3}\n"
     ]
    }
   ],
   "source": [
    "import java.util.HashMap; \n",
    "import java.util.Map;\n",
    "\n",
    "\n",
    "// 创建一个新的HashMap\n",
    "Map<String, Integer> numbers = new HashMap<>();\n",
    "\n",
    "// 使用put方法添加元素\n",
    "numbers.put(\"One\", 1);\n",
    "numbers.put(\"Two\", 2);\n",
    "numbers.put(\"Three\", 3);\n",
    "\n",
    "//输出: {One=1, Two-2, Three=3} \n",
    "System.out.println(numbers);\n",
    "\n",
    "//使用get方法根据键获取值\n",
    "int value = numbers.get(\"Two\");\n",
    "// 输出:2\n",
    "System.out.println(value);\n",
    "\n",
    "// 使用containsKey方法检查是否\t\t包含特定的键\n",
    "boolean result = numbers.containsKey(\"Three\");\n",
    "\n",
    "// 输出:true\n",
    "System.out.println(result);\n",
    "\n",
    "// 使用remove方法删除键值对 \n",
    "numbers.remove(\"Two\");\n",
    "\n",
    "//输出: {One=1, Three=3} \n",
    "System.out.println(numbers);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Six\n",
      "2: Two\n",
      "4: Four\n",
      "5: Five\n",
      "6: Six\n",
      "8: Eight\n"
     ]
    }
   ],
   "source": [
    "Map<Integer, String> m = new HashMap<>();\n",
    "m.put(5, \"Five\");\n",
    "m.put(8, \"Eight\");\n",
    "m.put(6, \"Six\");\n",
    "m.put(4, \"Four\");\n",
    "m.put(2, \"Two\");\n",
    "// 检索\n",
    "System.out.println(m.get(6));\n",
    "// Lambda forEach\n",
    "m.forEach((key, value) -> {\n",
    "    String msg = key + \": \" + value;\n",
    "    System.out.println(msg);\n",
    "});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{100=Hello, 102=Geeks, 103=Hello}\n"
     ]
    }
   ],
   "source": [
    "ConcurrentHashMap<Integer, String> m\n",
    "            = new ConcurrentHashMap<>();\n",
    "m.put(100, \"Hello\");\n",
    "m.put(101, \"Geeks\");\n",
    "m.put(102, \"Geeks\");\n",
    "// 移除\n",
    "m.remove(101, \"Geeks\");\n",
    "\n",
    "// 如果不存在，就添加，存在就不变更\n",
    "m.putIfAbsent(103, \"Hello\");\n",
    " \n",
    "// 替换\n",
    "m.replace(101, \"Hello\", \"For\");\n",
    "System.out.println(m);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Queue容器\n",
    "在Java中，Queue接口存在于java.util包中，表示一个元素的集合，这些元素以特定的顺序进行处理。它遵循先进先出（FIFO）原则，这意味着元素按照它们被添加到队列的顺序进行检索。\n",
    "Java中实现Queue的类有LinkedList，ArrayDeque和PriorityQueue。每个类都提供了不同的队列接口实现，具有不同的性能特性和功能。\n",
    "\n",
    "先进先出的意思：在队列中，最早进入队列的元素将是最早被处理和移除的元素。这种原则在计算机科学中非常重要，尤其是在处理队列时。它确保了添加到队列的第一个任务或项目是第一个被处理或移除的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "队列是:[6, 1, 8, 4, 7]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "从头部删除的元素是：6\n",
      "删除后的队列是:[1, 8, 4, 7]\n",
      "队列的头部是：1\n",
      "队列的大小是:4\n"
     ]
    }
   ],
   "source": [
    "import java.util.LinkedList; \n",
    "import java.util.Queue;\n",
    "\n",
    "\n",
    "// 创建一个新的队列\n",
    "Queue<Integer> q = new LinkedList<>();\n",
    "\n",
    "// 使用add方法添加元素\n",
    "q.add(6);\n",
    "q.add(1);\n",
    "q.add(8);\n",
    "q.add(4);\n",
    "q.add(7);\n",
    "\n",
    "//输出: [6, 1, 8, 4, 7]\n",
    "System.out.println(\"队列是:\"+ q);\n",
    "\n",
    "// 使用remove方法删除并返回队列头部的元素 \n",
    "int num1 = q.remove();\n",
    "\n",
    "// 输出:6\n",
    "System.out.println(\"从头部删除的元素是：\"+num1);\n",
    "System.out.println(\"删除后的队列是:\"+q);\n",
    "\n",
    "// 使用peek方法返回队列头部的元素,但不删除它\n",
    "int head= q.peek();\n",
    "\n",
    "// 输出:1\n",
    "System.out.println(\"队列的头部是：\"+head);\n",
    "\n",
    "// 使用size方法获取队列的大小\n",
    "int size = q.size();\n",
    "\n",
    "// 输出:4\n",
    "System.out.println(\"队列的大小是:\"+size);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Cat, Dog, Horse]\n",
      "Cat\n",
      "Cat\n"
     ]
    }
   ],
   "source": [
    "Deque<String> a = new ArrayDeque<>();\n",
    "// 使用 add()\n",
    "a.add(\"Dog\");\n",
    "// 使用 addFirst()\n",
    "a.addFirst(\"Cat\");\n",
    "// 使用 addLast()\n",
    "a.addLast(\"Horse\");\n",
    "// [Cat, Dog, Horse]\n",
    "System.out.println(a);\n",
    "// 访问元素\n",
    "System.out.println(a.peek());\n",
    "// 移除元素\n",
    "System.out.println(a.pop());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Collections 工具类\n",
    "在Java中，Collections是一个工具类，存在于java.util包中。它包含了一系列静态方法，主要用于操作和管理集合List，也有一些方法可以操作其他容器。\n",
    "\n",
    "1. sort()：此方法用于对List进行排序。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3, 4, 5, 8]\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(5, 3, 8, 1, 4);\n",
    "\n",
    "// 使用Collections.sort()方法进行排序 \n",
    "Collections.sort(list);\n",
    "\n",
    "// 输出:【1,3,4, 5, 8] \n",
    "System.out.println(list);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. reverse()：此方法用于反转List"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[5, 4, 3, 2, 1]\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);\n",
    "\n",
    "// 使用Collections.reverse()方法进行反转 \n",
    "Collections.reverse(list);\n",
    "\n",
    "// 输出: [5, 4, 3, 2, 1]\n",
    "System.out.println(list);\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. min()和max()：这两个方法分别用于找出集合中的最小值和最大值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最小值是: 1\n",
      "最大值是: 8\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(5, 3, 8, 1, 4);\n",
    "\n",
    "//使用Collections.min()Collections.max()方法找出最大值和最最小值;\n",
    "int min = Collections.min(list);\n",
    "int max = Collections.max(list);\n",
    "\n",
    "// 输出:1\n",
    "System.out.println(\"最小值是: \"+ min);\n",
    "\n",
    "// 输出:8\n",
    "System.out.println(\"最大值是: \"+ max);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4. shuffle()：此方法用于随机排列List中的元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3, 5, 2, 4]\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);\n",
    "\n",
    "//使用Collections.shuffle()方法进行随机排列\n",
    "Collections.shuffle(list);\n",
    "\n",
    "// 输出:[4,1,5,2,3] (结果可能会有所不同) \n",
    "System.out.println(list);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "5. binarySearch()：此方法用于在已排序的List中查找指定元素的索引。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "元素5的索引是：2\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(1, 3, 5, 7, 9);\n",
    "\n",
    "// 使用Collections.binarySearch()方法查找元素 \n",
    "int index = Collections.binarySearch(list, 5);\n",
    "\n",
    "// 输出:2\n",
    "System.out.println(\"元素5的索引是：\"+ index);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "6. fill()：此方法用于将List中的所有元素替换为指定元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 0, 0, 0, 0]\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "\n",
    "List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);\n",
    "\n",
    "//使用Collections.fill( )方法替换元素\n",
    "Collections.fill(list, 0);\n",
    "\n",
    "// 输出：[0, 0, 0, 0, 0] \n",
    "System.out.println(list);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "7. frequency()：此方法用于返回集合中指定元素的出现次数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#3: 3\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4);\n",
    "\n",
    "//使用Collections.frequency()方法计算元素的出现次数 \n",
    "int freq = Collections.frequency(list, 3);\n",
    "\n",
    "// 输出:3\n",
    "System.out.println(\"#3: \" + freq);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "8. replaceAll()：此方法用于将List中的所有出现的指定元素替换为另一个元素。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 9, 9, 3, 3, 3, 4, 4, 4, 4]\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "List<Integer> list = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4);\n",
    "\n",
    "// 使用Collections.replaceAll()方法替换元素\n",
    "Collections.replaceAll(list, 2, 9);\n",
    "\n",
    "//输出: [1, 9, 9, 3, 3, 3, 4, 4, 4, 4] \n",
    "System.out.println(list);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在Java中，Collections工具类的许多方法主要是为List接口设计的，例如sort()，reverse()等。\n",
    "\n",
    "然而，也有一些Collections类的方法可以用于其他类型的集合，如Set，Queue，甚至Map。\n",
    "\n",
    "例如，Collections类的frequency()方法可以用于任何Collection，包括List，Set和Queue，来计算指定元素在集合中的出现次数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "元素2出现的次数是:1\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 2, 3, 3, 3));\n",
    "\n",
    "//使用Collections.frequency()方法计算元素的出现次数 \n",
    "int freq = Collections.frequency(set, 2);\n",
    "\n",
    "// 输出:1\n",
    "System.out.println(\"元素2出现的次数是:\" + freq);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Collections类的emptySet()，emptyList()和emptyMap()方法可以用于创建不可变的空Set，List和Map。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "空Set: []\n",
      "空List: []\n",
      "空Map: {}\n"
     ]
    }
   ],
   "source": [
    "import java.util.*;\n",
    "\n",
    "\n",
    "Set<String> set = Collections.emptySet();\n",
    "List<String> list = Collections.emptyList(); \n",
    "Map<String, String> map = Collections.emptyMap();\n",
    "\n",
    "// 输出:[]\n",
    "System.out.println(\"空Set: \" + set);\n",
    "\n",
    "// 输出:[]\n",
    "System.out.println(\"空List: \"+ list);\n",
    "\n",
    "// 输出:{}\n",
    "System.out.println(\"空Map: \"+ map);\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **24 Lambda Expressions**\n",
    "\n",
    "Lambda表达式是一种匿名函数，它没有名称，但可以被当作函数使用。Lambda表达式主要用于简化函数式编程中的代码编写，它可以作为参数传递给方法，或者作为函数式接口的实现。\n",
    "## Lambda表达式的语法\n",
    "Lambda表达式的语法由三部分组成：参数列表、箭头符号和方法体。基本语法如下：\n",
    "```java\n",
    "(parameters) -> { body }\n",
    "```\n",
    "- 参数列表：指定方法的参数，可以是零个或多个参数。\n",
    "- 箭头符号：由\"->\"组成，用于分隔参数列表和方法体。\n",
    "- 方法体：包含了Lambda表达式的执行逻辑。\n",
    "\n",
    "Lambda表达式可以有不同的形式，取决于参数的个数和类型，以及方法体的复杂度。下面是一些Lambda表达式的示例：\n",
    "\n",
    "- 无参数的Lambda表达式：\n",
    "    ```java\n",
    "    () -> System.out.println(\"Hello, Lambda!\");\n",
    "    ```\n",
    "- 带有一个参数的Lambda表达式：\n",
    "    ```java\n",
    "    (name) -> System.out.println(\"Hello, \" + name + \"!\");\n",
    "    ```\n",
    " - 带有多个参数的Lambda表达式：\n",
    "    ```java\n",
    "    (x, y) -> {\n",
    "        int sum = x + y;\n",
    "        System.out.println(\"Sum: \" + sum);\n",
    "    };\n",
    "    ```\n",
    "- Lambda表达式可以有返回值，可以在方法体中使用return语句返回值：\n",
    "    ```java\n",
    "    (x, y) -> {\n",
    "        int sum = x + y;\n",
    "        return sum;\n",
    "    };\n",
    "    ```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "interface Summable \n",
    "{\n",
    "  public int combine(int a, int b);\n",
    "}\n",
    "\n",
    "public class MyApp \n",
    "{\n",
    "  public static void main(String[] args) {\n",
    "    Summable s = (x, y) -> x + y;\n",
    "    s.combine(2, 3); // 5\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4"
     ]
    }
   ],
   "source": [
    "import java.util.function.*;\n",
    "\n",
    "public class MyApp\n",
    "{\n",
    "  public static void main(String[] args) {\n",
    "    BinaryOperator<Integer> adder = (x, y) -> x + y;\n",
    "    adder.apply(2, 3); // 5\n",
    "\n",
    "    UnaryOperator<Integer> doubler = x -> x*2;\n",
    "    System.out.print(doubler.apply(2)); // 4\n",
    "\n",
    "  }\n",
    "}\n",
    "MyApp.main(null)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello\n"
     ]
    }
   ],
   "source": [
    "static void starter(Runnable s){\n",
    "    s.run();\n",
    "}\n",
    "\n",
    "public static void main(String[] args) {\n",
    "    Runnable r = () -> System.out.println(\"Hello\");\n",
    "    starter(r); // \"Hello\"\n",
    "}\n",
    "\n",
    "main(null)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lambda表达式的使用方法\n",
    "- Lambda表达式主要用于函数式接口，即只包含一个抽象方法的接口。函数式接口可以使用@FunctionalInterface注解进行标识。\n",
    "- Java提供了许多函数式接口，如Runnable、Consumer、Predicate等。可以使用Lambda表达式来实现这些接口的抽象方法，从而实现相应的功能。\n",
    "\n",
    "\n",
    "下面是一些Lambda表达式的使用示例\n",
    "\n",
    "- 使用Lambda表达式创建Runnable实例：\n",
    "    ```java\n",
    "    Runnable runnable = () -> {\n",
    "        System.out.println(\"Hello, Lambda!\");\n",
    "    };\n",
    "    ```\n",
    "- 使用Lambda表达式实现Consumer接口：\n",
    "    ```java\n",
    "    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);\n",
    "    numbers.forEach(n -> System.out.println(n));\n",
    "    ```\n",
    "- 使用Lambda表达式实现Predicate接口：\n",
    "    ```java\n",
    "    List<String> names = Arrays.asList(\"Alice\", \"Bob\", \"Charlie\", \"David\");\n",
    "    List<String> filteredNames = names.stream()\n",
    "                                    .filter(name -> name.length() > 5)\n",
    "                                    .collect(Collectors.toList());\n",
    "    ```\n",
    "\n",
    "## Lambda表达式的限制和注意事项\n",
    "\n",
    "在使用Lambda表达式时，需要注意以下几点：\n",
    "\n",
    "- Lambda表达式只能用于函数式接口，即只包含一个抽象方法的接口。\n",
    "- Lambda表达式不能有修改非final的外部变量，或者说Lambda表达式内部对外部变量是只读的。\n",
    "- Lambda表达式的参数类型可以省略，编译器可以根据上下文自动推断类型。\n",
    "- Lambda表达式可以有返回值，但对于单行方法体，返回值类型可以省略。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **25 文件访问与存储**\n",
    "## File类\n",
    "通过File类创建文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "true\n",
      "创建文件\n",
      "false\n",
      "创建文件结束\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "true\n"
     ]
    }
   ],
   "source": [
    "File f = new File(\"./test.txt\");\n",
    "System.out.println(f.exists());\n",
    "System.out.println(\"创建文件\");\n",
    "//成功会返回一个Boolean类型\n",
    "System.out.println(f.createNewFile());\n",
    "System.out.println(\"创建文件结束\");\n",
    "System.out.println(f.exists());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 文件类IO\n",
    "在字符流字符输入和输出流分别对应Reader和Writer，一个是读文件一个是写文件。对文件操作的实现类是FileReader，用该对象即可实现文件的读取。FileWriter是文件写入实现类。\n",
    "\n",
    "### 文件流读取\n",
    "FileReader构造方法可以用于指定编码，创造FileReader对象。\n",
    "### 字符流转换\n",
    "Java提供了BufferdReader类来操作文件流。BufferdReader的构造方法的第一个参数是Reader字符流，那么它就可以操作任何继承了该接口的实现类。\n",
    "BufferdReader读取文件流中提供了readLine()方法读取文件一行内容。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "java.io.FileReader@5eda7298\n",
      "01000111 01101111 01101111 01100100 00100000 01101101 01101111 01110010 01101110 01101001 01101110 01100111 00101100 00100000 01110100 01101000 01100101 00100000 01110011 01110101 01101110 00100000 01101001 01110011 00100000 01110010 01101001 01110011 01101001 01101110 01100111 00100000 01110011 01101111 00100000 01100010 01100101 01100001 01110101 01110100 01101001 01100110 01110101 01101100 01101100 01111001 00100000 01110100 01101111 01100100 01100001 01111001 00100000 00100001\n"
     ]
    }
   ],
   "source": [
    "try {\n",
    "    FileReader fileReader = new FileReader(\"input.txt\");\n",
    "    System.out.println(fileReader);\n",
    "    BufferedReader reader = new BufferedReader(fileReader);\n",
    "    System.out.println(reader.readLine());\n",
    "\n",
    "}catch (IOException e){\n",
    "    e.printStackTrace();\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 文件流写入\n",
    "FileWriter的对象提供了诸如append(),write(),close()方法，向文件中写入内容。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [],
   "source": [
    "try {\n",
    "    FileWriter fileWriter = new FileWriter(new File(\"test.txt\"));\n",
    "    fileWriter.write(\"Hello World\");\n",
    "    fileWriter.close();\n",
    "\n",
    "}catch (IOException e){\n",
    "    e.printStackTrace();\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CSV解析\n",
    "读取CSv文件指定列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Name, \"Braund, \"Cumings, \"Heikkinen, \"Futrelle, \"Allen, \"Moran, \"McCarthy, \"Palsson, \"Johnson, \"Nasser, \"Sandstrom, \"Bonnell, \"Saundercock, \"Andersson, \"Vestrom, \"Hewlett, \"Rice, \"Williams, \"Vander Planke, \"Masselmani]\n"
     ]
    }
   ],
   "source": [
    "public class ReadCSV {\n",
    "\n",
    "    BufferedReader br=null;\n",
    "    String line = null;\n",
    "\n",
    "    public ReadCSV(){}\n",
    "\n",
    "    //获取某一列返回数组\n",
    "    public List<String> getOneColumn(String path,int column){   //参数为路径和指定列\n",
    "        //该列表用于存储读取的指定列元素\n",
    "        ArrayList arrayList = new ArrayList();\n",
    "\n",
    "        try {\n",
    "            br = new BufferedReader(new FileReader(path));\n",
    "\n",
    "            //循环读取每行的指定列元素\n",
    "            while ((line = br.readLine()) != null) {\n",
    "                //\",\"分割每行第column列\n",
    "                // System.out.println(line.split(\",\")[column]);\n",
    "                String a= line.split(\",\")[column];\n",
    "                if(a !=null && a !=\"\"){arrayList.add(a);}\n",
    "            }\n",
    "        }catch (Exception e){\n",
    "            e.printStackTrace();\n",
    "        }finally {\n",
    "            try {\n",
    "                br.close();\n",
    "            } catch (IOException e) {\n",
    "                e.printStackTrace();\n",
    "            }\n",
    "        }\n",
    "\n",
    "        return arrayList;\n",
    "    }\n",
    "}\n",
    "\n",
    "ReadCSV readCSV = new ReadCSV();\n",
    "ArrayList result = (ArrayList)readCSV.getOneColumn(\"train.csv\",3);\n",
    "System.out.println(result);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[Name, \"Braund, \"Cumings, \"Heikkinen, \"Futrelle, \"Allen, \"Moran, \"McCarthy, \"Palsson, \"Johnson, \"Nasser, \"Sandstrom, \"Bonnell, \"Saundercock, \"Andersson, \"Vestrom, \"Hewlett, \"Rice, \"Williams, \"Vander Planke, \"Masselmani]\n"
     ]
    }
   ],
   "source": [
    "ReadCSV readCSV = new ReadCSV();\n",
    "List<String> maps = readCSV.getOneColumn(\"train.csv\", 3);\n",
    "System.out.println(maps);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 写入txt文件\n",
    "使用FileWriter方式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test2 done!\n"
     ]
    }
   ],
   "source": [
    "try {\n",
    "    String content = \"测试使用字符串\";\n",
    "    String filePath = \"test2.txt\";\n",
    "    File file = new File(filePath);\n",
    "    //文件不存在时候，主动创建文件。\n",
    "    if(!file.exists()){\n",
    "        file.createNewFile();\n",
    "    }\n",
    "    //清空文件重写，要想追加写入，则将FileOutputStream构造函数中第二个参数变为true。\n",
    "    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath,false),\"UTF-8\"));\n",
    "    bw.write(content);\n",
    "    bw.write(\"\\r\\n\");\n",
    "    // 生成时间字符串\n",
    "    bw.write(new Date().toString());\n",
    "    bw.close();\n",
    "    System.out.println(\"test2 done!\");\n",
    "     \n",
    "} catch (Exception e) {\n",
    "    // TODO: handle exception\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取txt文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试使用字符串Mon Apr 01 10:18:22 CST 2024\n"
     ]
    }
   ],
   "source": [
    "String filePath = \"test2.txt\";\n",
    "//设置默认编码\n",
    "String charset = \"UTF-8\";\n",
    "File file = new File(filePath);\n",
    "\n",
    "if(file.isFile() && file.exists()){\n",
    "    try {\n",
    "        FileInputStream fileInputStream = new FileInputStream(filePath);\n",
    "        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, charset);\n",
    "        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);\n",
    "            \n",
    "        StringBuffer sb = new StringBuffer();\n",
    "        String text = null;\n",
    "        while((text = bufferedReader.readLine()) != null){\n",
    "            sb.append(text);\n",
    "        }\n",
    "        System.out.println(sb.toString());\n",
    "    } catch (Exception e) {\n",
    "        // TODO: handle exception\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## JSON文件的读写\n",
    "\n",
    "示例JSON文件内容如下： \n",
    "```json\n",
    "{\n",
    "    \"type\": \"FeatureCollection\",\n",
    "    \"features\": [\n",
    "        {\n",
    "            \"type\": \"Feature\",\n",
    "            \"properties\": {\n",
    "                \"name\": \"Yuen Long\",\n",
    "                \"ID_0\": 102,\n",
    "                \"ID_1\": 18,\n",
    "                \"ISO\": \"HKG\"\n",
    "            },\n",
    "            \"geometry\": {\n",
    "                \"type\": \"Polygon\",\n",
    "                \"coordinates\": [[[114.084511, 22.519991], [114.075668, 22.517466], [114.078194, 22.516203], [114.079460, 22.516623], [114.082825, 22.519150], [114.084511, 22.519991]]]\n",
    "            }\n",
    "        }\n",
    "    ]\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Yuen Long123\n"
     ]
    }
   ],
   "source": [
    "%jars json.jar\n",
    "import org.json.*;\n",
    "\n",
    "ArrayList<String> list = new ArrayList<String>(); \n",
    "//读取json文件\n",
    "try {\n",
    "    BufferedReader br = new BufferedReader(new FileReader(\"test.json\"));\n",
    "    BufferedWriter bw=new BufferedWriter(new FileWriter(\"newFile.json\"));\n",
    "\n",
    "    String str=null;\n",
    "    String data=\"\";\n",
    "    while((str=br.readLine())!=null) {\n",
    "        data=data+str+\"\\n\";\n",
    "    }\n",
    "    // System.out.println(data);\n",
    "\n",
    "    JSONObject dataJson = new JSONObject(data);\n",
    "    JSONArray features=dataJson.getJSONArray(\"features\");\n",
    "\n",
    "    for (int i = 0; i < features.length(); i++) {  \n",
    "        JSONObject info = features.getJSONObject(i);// 获取features数组的第i个json对象  \n",
    "        JSONObject properties = info.getJSONObject(\"properties\");// 找到properties的json对象  \n",
    "        String name = properties.getString(\"name\");// 读取properties对象里的name字段值\n",
    "\n",
    "        properties.put(\"NAMEID\", name+\"123\");// 添加NAMEID字段  \n",
    "        System.out.println(properties.getString(\"NAMEID\")); \n",
    "\n",
    "        properties.remove(\"ISO\");// 删除ISO字段 \n",
    "        String ws=dataJson.toString();\n",
    "        // System.out.println(ws);\n",
    "        bw.write(ws);  \n",
    "        bw.flush();  \n",
    "        br.close();  \n",
    "        bw.close();\n",
    "    }\n",
    "}\n",
    "catch (FileNotFoundException e) {\n",
    "    // TODO Auto-generated catch block\n",
    "    e.printStackTrace();\n",
    "}// 读取原始json文件 \n",
    " catch (IOException e) {\n",
    "    // TODO Auto-generated catch block\n",
    "    e.printStackTrace();\n",
    "} catch (JSONException e) {\n",
    "    // TODO Auto-generated catch block\n",
    "    e.printStackTrace();\n",
    "}    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **26 多线程**\n",
    "\n",
    "#### 什么是线程\n",
    "\n",
    "线程是程序执行的基本单位，是一种轻量级的进程，它可以让程序在同一时间内执行多个任务。\n",
    "\n",
    "#### 线程状态\n",
    "\n",
    "线程可以处于以下几种状态：\n",
    "\n",
    "- NEW：初始状态，线程被创建但未启动。\n",
    "- RUNNABLE：运行状态，线程正在执行或等待执行。\n",
    "- BLOCKED：阻塞状态，线程因为等待锁的释放而被阻塞。\n",
    "- WAITING：等待状态，线程等待其他线程执行特定操作。\n",
    "- TIMED_WAITING：计时等待状态，线程等待其他线程执行特定操作，但等待时间有限制。\n",
    "- TERMINATED：终止状态，线程执行完毕或被中断。\n",
    "\n",
    "#### 线程生命周期\n",
    "\n",
    "线程从创建到终止的整个过程称为线程生命周期。线程生命周期包括以下几个阶段：\n",
    "\n",
    "- 新建（NEW）：当线程对象被创建时，它处于新建状态。\n",
    "- 就绪（RUNNABLE）：当线程对象调用start()方法后，线程进入就绪状态，等待系统分配执行时间。\n",
    "- 运行（RUNNING）：当线程获得执行时间时，线程进入运行状态，执行它的run()方法。\n",
    "- 阻塞（BLOCKED）：线程等待获取一个排它锁，或等待IO操作完成等情况时，线程进入阻塞状态。\n",
    "- 等待（WAITING）：线程等待其他线程执行特定操作时，线程进入等待状态。\n",
    "- 计时等待（TIMED_WAITING）：线程等待其他线程执行特定操作，但等待时间有限制时，线程进入计时等待状态。\n",
    "- 终止（TERMINATED）：当线程的run()方法执行完毕或被中断时，线程进入终止状态。\n",
    "\n",
    "\n",
    "## 线程的基础知识\n",
    "- Java的线程是通过java.lang.Thread类来实现的。\n",
    "- 每个Java程序至少有一个线程(主线程)，当一个Java程序程序启动时，JVM会创建主线程，并在该线程中调用程序的main()方法；\n",
    "- 可以通过创建Thread的实例来创建新的线程。\n",
    "- 每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的，方法run()称为线程体。\n",
    "- 通过调用Thread类的start()方法来启动一个线程。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程的创建和使用\n",
    "有两种方式创建新的线程。\n",
    "- 第一种：声明实现 Runnable 接口的类 \n",
    "  - 定义线程类，实现Runnable接口。\n",
    "  - 实例化Thread对象。\n",
    "    ```java\n",
    "    Thread myThread = new Thread(Runnable target);\n",
    "                        //target为Runnable接口类型对象\n",
    "    ```\n",
    "  - 调用start()方法启动线程。例：\n",
    "    ```java\n",
    "      myThread.start();\n",
    "    ```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Main Thread:-------0\n",
      "Main Thread:-------1\n",
      "Runner1: 0\n",
      "Runner1: 1\n",
      "Main Thread:-------2\n",
      "Main Thread:-------3\n",
      "Main Thread:-------4\n",
      "Runner1: 2\n",
      "Main Thread:-------5\n",
      "Main Thread:-------6\n",
      "Main Thread:-------7\n",
      "Main Thread:-------8\n",
      "Runner1: 3\n",
      "Runner1: 4\n",
      "Main Thread:-------9\n",
      "Runner1: 5\n",
      "Runner1: 6\n",
      "Runner1: 7\n",
      "Runner1: 8\n",
      "Runner1: 9\n"
     ]
    }
   ],
   "source": [
    "public class TestRunnable {\n",
    "    public static void main(String args[]) {\n",
    "      Runner1 r = new Runner1();\n",
    "      //r.run();\n",
    "      Thread t = new Thread(r);\n",
    "      t.start();\n",
    "  \n",
    "      for(int i=0; i<10; i++) {\n",
    "        System.out.println(\"Main Thread:-------\" + i);\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "\n",
    "class Runner1 implements Runnable {\n",
    "    public void run() {\n",
    "        for(int i=0; i<10; i++) {\n",
    "            System.out.println(\"Runner1: \" + i);\n",
    "        }\n",
    "    }\n",
    "}\n",
    "TestRunnable.main(null)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 第二种：将类声明为 Thread 的子类\n",
    "    - 定义一个Thread类的子类，并重写run()方法。如：\n",
    "        ```java\n",
    "        class MyThread extends Thread {\n",
    "            public void run() {…}\n",
    "        }\n",
    "        ```\n",
    "    - 然后生成该类的实例对象。例：\n",
    "        ```java\n",
    "        MyThread myThread = new MyThread();\n",
    "        ```\n",
    "    - 调用start()方法启动线程。\n",
    "        ```java\n",
    "        myThread.start();\n",
    "        ```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Runner1: 0\n",
      "Runner1: 1\n",
      "Runner1: 2\n",
      "Main Thread:-------0\n",
      "Main Thread:-------1\n",
      "Runner1: 3\n",
      "Runner1: 4\n",
      "Runner1: 5\n",
      "Main Thread:-------2\n",
      "Main Thread:-------3\n",
      "Runner1: 6\n",
      "Main Thread:-------4\n",
      "Runner1: 7\n",
      "Main Thread:-------5\n",
      "Runner1: 8\n",
      "Main Thread:-------6\n",
      "Runner1: 9\n",
      "Main Thread:-------7\n",
      "Main Thread:-------8\n",
      "Main Thread:-------9\n"
     ]
    }
   ],
   "source": [
    "public class TestThread {\n",
    "  public static void main(String args[]) {\n",
    "    MyThread t = new MyThread();\n",
    "    t.start();\n",
    "\n",
    "    for(int i=0; i<10; i++) {\n",
    "       System.out.println(\"Main Thread:-------\" + i);\n",
    "    }\n",
    "  }\n",
    "}\n",
    "\n",
    "class MyThread extends Thread {\n",
    "  public void run() {\n",
    "    for(int i=0; i<10; i++) {\n",
    "        System.out.println(\"Runner1: \" + i);\n",
    "    }\n",
    "  }\n",
    "}\n",
    "TestThread.main(null)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### sleep方法\n",
    "使得当前线程休眠（暂停执行millis毫秒）。\n",
    "```java\n",
    "public static void sleep(long millis) \n",
    "                             throws InterruptedException\n",
    "```\n",
    "由于是静态方法，sleep可以由类名直接调用：\n",
    "```java\n",
    "Thread.sleep(…);\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=====Mon Apr 01 12:17:34 CST 2024=====\n",
      "=====Mon Apr 01 12:17:35 CST 2024=====\n",
      "=====Mon Apr 01 12:17:36 CST 2024=====\n",
      "=====Mon Apr 01 12:17:37 CST 2024=====\n",
      "=====Mon Apr 01 12:17:38 CST 2024=====\n",
      "=====Mon Apr 01 12:17:39 CST 2024=====\n",
      "=====Mon Apr 01 12:17:40 CST 2024=====\n",
      "=====Mon Apr 01 12:17:41 CST 2024=====\n",
      "=====Mon Apr 01 12:17:42 CST 2024=====\n",
      "=====Mon Apr 01 12:17:43 CST 2024=====\n"
     ]
    }
   ],
   "source": [
    "public class TestSleep {\n",
    "    public static void main(String args[]) {\n",
    "       MyThread1 th = new MyThread1();\n",
    "       th.start();\n",
    "       try {\n",
    "          Thread.sleep(10000);\n",
    "       } catch(InterruptedException e) {}\n",
    "       th.interrupt();\n",
    "    }\n",
    "}\n",
    "\n",
    "class MyThread1 extends Thread {\n",
    "    //boolean flag = true;\n",
    "    public void run() {   //能否在这使用throws InterruptedException\n",
    "        while(true) {        //while(flag) {\n",
    "        System.out.println(\"=====\" + new Date() + \"=====\");\n",
    "        try {\n",
    "            sleep(1000);\n",
    "        } catch(InterruptedException e) {  return;  }\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "TestSleep.main(null)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### join方法\n",
    "等待该线程结束。\n",
    "```java\n",
    "public final void join() \n",
    "    throws InterruptedException\n",
    "```\n",
    "当某一个线程要等待另一个线程时，它自己会进入等待状态，直到它等待的事情完成了，它才又会回到就绪状态，准备被CPU挑选执行。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I am thread1, Mon Apr 01 12:36:03 CST 2024\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I am thread1, Mon Apr 01 12:36:04 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:05 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:06 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:07 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:08 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:09 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:10 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:11 CST 2024\n",
      "I am thread1, Mon Apr 01 12:36:12 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n",
      "I am main thread, Mon Apr 01 12:36:13 CST 2024\n"
     ]
    }
   ],
   "source": [
    "class MyThread2 extends Thread {\n",
    "    MyThread2(String s) {  super(s);  }\n",
    "    public void run() {\n",
    "       for(int i=1; i<=10; i++) {\n",
    "          System.out.println(\"I am \" + getName()+ \", \"+new Date());\n",
    "          try {\n",
    "             sleep(1000);\n",
    "          } catch(InterruptedException e) { return; }\n",
    "       }\n",
    "    }\n",
    "  }\n",
    "  \n",
    "  public class TestJoin {\n",
    "    public static void main(String args[]) {\n",
    "       MyThread2 thread1 = new MyThread2(\"thread1\");\n",
    "       thread1.start();\n",
    "       try {\n",
    "          thread1.join();\n",
    "       } catch(InterruptedException e) {}\n",
    "       for(int i=1; i<=10; i++) {\n",
    "          System.out.println(\"I am main thread, \"+ new Date());\n",
    "       }\n",
    "    }\n",
    "  }\n",
    "  TestJoin.main(null)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### yield方法\n",
    "暂停当前正在执行的线程对象（使其从执行状态转换到就绪状态），并执行其他线程。 \n",
    "\n",
    "yield 即 \"谦让\"，也是 Thread 类的方法。它让掉当前线程 CPU 的时间片，使正在运行中的线程重新变成就绪状态，并重新竞争 CPU 的调度权。它可能会获取到，也有可能被其他线程获取到。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "t1: 1\n",
      "t1: 2\n",
      "thread2: 1\n",
      "thread2: 2\n",
      "t1: 3\n",
      "t1: 4\n",
      "t1: 5\n",
      "thread2: 3\n",
      "thread2: 4\n",
      "t1: 6\n",
      "t1: 7\n",
      "t1: 8\n",
      "t1: 9\n",
      "thread2: 5\n",
      "t1: 10\n",
      "t1: 11\n",
      "t1: 12\n",
      "thread2: 6\n",
      "thread2: 7\n",
      "thread2: 8\n",
      "t1: 13\n",
      "t1: 14\n",
      "thread2: 9\n",
      "t1: 15\n",
      "thread2: 10\n",
      "thread2: 11\n",
      "t1: 16\n",
      "thread2: 12\n",
      "t1: 17\n",
      "thread2: 13\n",
      "t1: 18\n",
      "thread2: 14\n",
      "t1: 19\n",
      "thread2: 15\n",
      "t1: 20\n",
      "thread2: 16\n",
      "thread2: 17\n",
      "thread2: 18\n",
      "thread2: 19\n",
      "thread2: 20\n"
     ]
    }
   ],
   "source": [
    "public class TestYield {\n",
    "    public static void main(String args[]) {\n",
    "      MyThread3 t1 = new MyThread3(\"t1\");\n",
    "      MyThread3 thread2 = new MyThread3(\"thread2\");\n",
    "      t1.start();\n",
    "      thread2.start();\n",
    "      try {\n",
    "        Thread.sleep(3000);\n",
    "     } catch(InterruptedException e) {}\n",
    "    }\n",
    "}\n",
    "  \n",
    "class MyThread3 extends Thread {\n",
    "    MyThread3(String s) {  super(s);  }\n",
    "\n",
    "    public void run() {\n",
    "        for(int i=1; i<=20; i++) {\n",
    "            System.out.println(getName() + \": \" + i);\n",
    "            if(i%5 == 0) {\n",
    "                Thread.yield();\n",
    "            }\n",
    "        }\n",
    "    }\n",
    "}\n",
    "TestYield.main(null)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 线程的优先级别\n",
    "Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调度哪个线程来执行。\n",
    "线程的优先级用数字表示，范围从1到10，一个线程的缺省优先级是5。\n",
    "```java\n",
    "Thread.MIN_PRIORITY = 1 \n",
    "Thread.MAX_PRIORITY = 10\n",
    "Thread.NORM_PRIORITY = 5\n",
    "```\n",
    "使用下述方法获得或设置线程对象优先级：\n",
    "```java\n",
    "int getPriority()\n",
    "void setPriority(int newPriority)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "T1: 1\n",
      "T1: 2\n",
      "-----T2: 1\n",
      "-----T2: 2\n",
      "T1: 3\n",
      "T1: 4\n",
      "T1: 5\n",
      "-----T2: 3\n",
      "-----T2: 4\n",
      "T1: 6\n",
      "T1: 7\n",
      "-----T2: 5\n",
      "T1: 8\n",
      "-----T2: 6\n",
      "-----T2: 7\n",
      "T1: 9\n",
      "T1: 10\n",
      "T1: 11\n",
      "-----T2: 8\n",
      "T1: 12\n",
      "-----T2: 9\n",
      "T1: 13\n",
      "-----T2: 10\n",
      "T1: 14\n",
      "-----T2: 11\n",
      "T1: 15\n",
      "-----T2: 12\n",
      "T1: 16\n",
      "-----T2: 13\n",
      "T1: 17\n",
      "-----T2: 14\n",
      "T1: 18\n",
      "-----T2: 15\n",
      "T1: 19\n",
      "-----T2: 16\n",
      "T1: 20\n",
      "-----T2: 17\n",
      "-----T2: 18\n",
      "-----T2: 19\n",
      "-----T2: 20\n"
     ]
    }
   ],
   "source": [
    "public class TestPriority {\n",
    "    public static void main(String args[]) {\n",
    "      Thread t1 = new Thread(new T1());\n",
    "      Thread t2 = new Thread(new T2());\n",
    "      t1.setPriority(Thread.NORM_PRIORITY + 3);\n",
    "      t1.start();\n",
    "      t2.start();\n",
    "      try {\n",
    "        Thread.sleep(3000);\n",
    "     } catch(InterruptedException e) {}\n",
    "    }\n",
    "  }\n",
    "  class T1 implements Runnable {\n",
    "    public void run() {\n",
    "      for(int i=1; i<=20; i++) {\n",
    "        System.out.println(\"T1: \" + i);\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "  class T2 implements Runnable {\n",
    "    public void run() {\n",
    "      for(int i=1; i<=20; i++) {\n",
    "        System.out.println(\"-----T2: \" + i);\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "  TestPriority.main(null);  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程互斥\n",
    "\n",
    "### 1.什么是锁\n",
    "\n",
    "在多线程编程中，锁是用来控制线程对共享资源的访问的机制，可以避免多个线程同时对共享资源进行修改，从而保证数据的一致性和正确性。\n",
    "\n",
    "- 在Java语言中，引入了对象互斥锁的概念，保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记，这个标记保证在任一时刻，只能有一个线程访问该对象。\n",
    "- 关键字synchronized来与对象的互斥锁联系。当某个对象synchronized修饰时，表明该对象在任一时刻只能由一个线程访问。\n",
    "- synchronized的使用方法：\n",
    "    ```java\n",
    "    synchronized(this) {…} \n",
    "    ```\n",
    "- synchronized还可放在方法声明中，表示整个方法为同步方法，例如：\n",
    "    ```java\n",
    "    public synchronized void add(String name) {…}\n",
    "    ```\n",
    "- 注意：使用synchronized不当可能会使系统发生死锁。\n",
    "- 锁的释放，通常有几种方式：\n",
    "    - 执行完锁定的程序代码后，锁就会自动释放。\n",
    "    - 遇到return语句。\n",
    "    - 发生了异常。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Producer1 make data count: 1\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "Producer2 make data count: 2\n",
      "Producer2 make data count: 3\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer1 make data count: 1\n",
      "---Consumer1 use data count: 1\n",
      "Producer1 make data count: 1\n",
      "Producer1 make data count: 2\n",
      "Producer1 make data count: 3\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "Producer2 make data count: 3\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer1 make data count: 1\n",
      "Producer1 make data count: 2\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer1 make data count: 1\n",
      "Producer1 make data count: 2\n",
      "Producer2 make data count: 3\n",
      "Producer1 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "Producer2 make data count: 3\n",
      "---Consumer1 use data count: 3\n",
      "Producer2 make data count: 3\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer1 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "Producer1 make data count: 3\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "Producer2 make data count: 2\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer1 make data count: 1\n",
      "---Consumer1 use data count: 1\n",
      "Producer1 make data count: 1\n",
      "Producer1 make data count: 2\n",
      "Producer1 make data count: 3\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "Producer1 make data count: 2\n",
      "Producer1 make data count: 3\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "Producer2 make data count: 2\n",
      "---Consumer1 use data count: 2\n",
      "Producer1 make data count: 2\n",
      "Producer1 make data count: 3\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "Producer1 make data count: 3\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "---Consumer1 use data count: 4\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "Producer2 make data count: 2\n",
      "Producer2 make data count: 3\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "Producer2 make data count: 2\n",
      "Producer2 make data count: 3\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "Producer2 make data count: 2\n",
      "Producer2 make data count: 3\n",
      "Producer2 make data count: 4\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "Producer2 make data count: 5\n",
      "---Consumer1 use data count: 5\n",
      "---Consumer1 use data count: 4\n",
      "---Consumer1 use data count: 3\n",
      "---Consumer1 use data count: 2\n",
      "---Consumer1 use data count: 1\n",
      "Producer2 make data count: 1\n",
      "Producer1 make data count: 2\n",
      "Producer1 make data count: 3\n",
      "Producer1 make data count: 4\n",
      "Producer1 make data count: 5\n"
     ]
    },
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
      "\u001b[1;31m请查看单元格中的代码，以确定故障的可能原因。\n",
      "\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
      "\u001b[1;31m有关更多详细信息，请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
     ]
    }
   ],
   "source": [
    "//先设计一个库存用的程序：\n",
    "public class Storage {\n",
    "    private int count;\n",
    "    private int size;\n",
    "     \n",
    "    public Storage(int s) {\n",
    "        size = s;\n",
    "    }\n",
    "     \n",
    "    public synchronized void addData(String n) {\n",
    "       while (count == size) {\n",
    "         try {\n",
    "            this.wait();\n",
    "         } catch (InterruptedException e) { }\n",
    "       }\n",
    "         \n",
    "       this.notify();\n",
    "       count ++;\n",
    "       System.out.println(n + \" make data count: \" + count);\n",
    "    }\n",
    "\n",
    "    public synchronized void delData(String n) {  \n",
    "       while (count == 0) {\n",
    "          try {\n",
    "             this.wait();\n",
    "          } catch (InterruptedException e) { }\n",
    "       }\n",
    "         \n",
    "       this.notify();\n",
    "       System.out.println(\"---\" + n + \" use data count: \"\n",
    "                                                + count);\n",
    "       count --;\n",
    "    }\t\n",
    " }\n",
    "\n",
    " //生产者的程序代码：\n",
    "public class Producer extends Thread {\n",
    "    private String name;\n",
    "    private Storage s;\n",
    "     \n",
    "    public Producer(String n, Storage s) {\n",
    "       name = n;\n",
    "       this.s = s;\n",
    "    }\n",
    "     \n",
    "    public void run() {\n",
    "      //  while(true) {                   \n",
    "      for(int i=0; i<100; i++) {\n",
    "          s.addData(name);\n",
    " \n",
    "          try {\n",
    "             sleep((int)Math.random()*3000);\n",
    "          } catch (InterruptedException e) { } \n",
    "       }\n",
    "    }\n",
    " }\n",
    "\n",
    " //消费者的程序代码：\n",
    "public class Consumer extends Thread {\n",
    "    private String name;\n",
    "    private Storage s;\n",
    "     \n",
    "    public Consumer(String n, Storage s) {\n",
    "       name = n;\n",
    "       this.s = s;\n",
    "    }\n",
    "     \n",
    "    public void run() {\n",
    "      //  while(true) {              \n",
    "      for(int i=0; i<100; i++) {\n",
    "          s.delData(name);\n",
    "             \n",
    "          try {\n",
    "             sleep((int)Math.random()*1000);\n",
    "          } catch (InterruptedException e) { } \n",
    "       }\n",
    "    }\n",
    " }\n",
    "\n",
    " //测试程序代码：\n",
    "public class Test {\n",
    "    public static void main(String argv[]) {\n",
    "       Storage s = new Storage(5);\n",
    "       Producer p1 = new Producer(\"Producer1\", s);\n",
    "       Producer p2 = new Producer(\"Producer2\", s);\n",
    "       Consumer c1 = new Consumer(\"Consumer1\", s);\n",
    " \n",
    "       p1.start();\n",
    "       p2.start();\n",
    "       c1.start();\n",
    "\n",
    "       try {\n",
    "         Thread.sleep(100);\n",
    "      } catch(InterruptedException e) {}\n",
    "    }\n",
    "}\n",
    "Test.main(null);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.锁的种类\n",
    "\n",
    "#### 2.1. synchronized关键字\n",
    "\n",
    "`synchronized`关键字用于修饰方法或代码块，确保同一时间只有一个线程执行被修饰的代码。具体来说，synchronized关键字提供了以下两种锁机制：\n",
    "\n",
    "- 对象锁：每个对象都有一个内置的锁，被synchronized关键字修饰的方法或代码块被称为对象锁。\n",
    "- 类锁：每个类也有一个内置的锁，被synchronized关键字修饰的静态方法或代码块被称为类锁。\n",
    "\n",
    "#### 2.2.可重入锁\n",
    "\n",
    "`ReentrantLock`是Java提供的一个可重入锁实现，相比于synchronized关键字，ReentrantLock提供了更多的锁机制和控制，如公平锁和可中断锁等。\n",
    "\n",
    "```java\n",
    "ReentrantLock lock = new ReentrantLock();\n",
    "\n",
    "lock.lock();  // 获取锁\n",
    "try {\n",
    "    // 临界区代码\n",
    "} finally {\n",
    "    lock.unlock();  // 释放锁\n",
    "}\n",
    "```\n",
    "\n",
    "#### 2.3.读写锁\n",
    "\n",
    "`ReadWriteLock`是Java提供的一个读写锁实现，可以提高共享资源的访问效率。读写锁允许多个线程同时读取共享资源，但只允许一个线程写入共享资源。\n",
    "\n",
    "```java\n",
    "ReadWriteLock lock = new ReentrantReadWriteLock();\n",
    "\n",
    "lock.readLock().lock();  // 获取读锁\n",
    "try {\n",
    "    // 读取共享资源\n",
    "} finally {\n",
    "    lock.readLock().unlock();  // 释放读锁\n",
    "}\n",
    "\n",
    "lock.writeLock().lock();  // 获取写锁\n",
    "try {\n",
    "    // 修改共享资源\n",
    "} finally {\n",
    "    lock.writeLock().unlock();  // 释放写锁\n",
    "}\n",
    "```\n",
    "\n",
    "#### 2.4. 冲压锁\n",
    "\n",
    "`StampedLock`是Java提供的一种乐观锁实现，可以提高读操作的并发性和性能。\n",
    "\n",
    "```java\n",
    "StampedLock lock = new StampedLock();\n",
    "long stamp = lock.tryOptimisticRead();  // 获取乐观读锁\n",
    "\n",
    "// 读取共享资源\n",
    "if (!lock.validate(stamp)) {\n",
    "    stamp = lock.readLock();  // 获取悲观读锁\n",
    "    try {\n",
    "        // 读取共享资源\n",
    "    } finally {\n",
    "        lock.unlockRead(stamp);  // 释放读锁\n",
    "    }\n",
    "}\n",
    "```\n",
    "\n",
    "### 3.锁的特点\n",
    "\n",
    "不同种类的锁有不同的特点：\n",
    "\n",
    "- synchronized关键字是Java内置的锁机制，使用方便，但锁粒度较大，无法实现更细粒度的控制。\n",
    "- ReentrantLock提供了更多的锁机制和控制，"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ThreadPoolExecutor 类\n",
    "线程池实现类 ThreadPoolExecutor 是 Executor 框架最核心的类。\n",
    "```java\n",
    "    /**\n",
    "     * 用给定的初始参数创建一个新的ThreadPoolExecutor。\n",
    "     */\n",
    "    public ThreadPoolExecutor(int corePoolSize,//线程池的核心线程数量\n",
    "                              int maximumPoolSize,//线程池的最大线程数\n",
    "                              long keepAliveTime,//当线程数大于核心线程数时，多余的空闲线程存活的最长时间\n",
    "                              TimeUnit unit,//时间单位\n",
    "                              BlockingQueue<Runnable> workQueue,//任务队列，用来储存等待执行任务的队列\n",
    "                              ThreadFactory threadFactory,//线程工厂，用来创建线程，一般默认即可\n",
    "                              RejectedExecutionHandler handler//拒绝策略，当提交的任务过多而不能及时处理时，我们可以定制策略来处理任务\n",
    "                               ) {\n",
    "        if (corePoolSize < 0 ||\n",
    "            maximumPoolSize <= 0 ||\n",
    "            maximumPoolSize < corePoolSize ||\n",
    "            keepAliveTime < 0)\n",
    "            throw new IllegalArgumentException();\n",
    "        if (workQueue == null || threadFactory == null || handler == null)\n",
    "            throw new NullPointerException();\n",
    "        this.corePoolSize = corePoolSize;\n",
    "        this.maximumPoolSize = maximumPoolSize;\n",
    "        this.workQueue = workQueue;\n",
    "        this.keepAliveTime = unit.toNanos(keepAliveTime);\n",
    "        this.threadFactory = threadFactory;\n",
    "        this.handler = handler;\n",
    "    }\n",
    "```\n",
    "ThreadPoolExecutor 3 个最重要的参数：\n",
    "- corePoolSize : 核心线程数线程数定义了最小可以同时运行的线程数量。\n",
    "- maximumPoolSize : 当队列中存放的任务达到队列容量的时候，当前可以同时运行的线程数量变为最大线程数。\n",
    "- workQueue: 当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数，如果达到的话，新任务就会被存放在队列中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "vscode": {
     "languageId": "java"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Running task 0 on thread pool-1-thread-1\n",
      "Running task 4 on thread pool-1-thread-5\n",
      "Running task 3 on thread pool-1-thread-4\n",
      "Running task 2 on thread pool-1-thread-3\n",
      "Running task 1 on thread pool-1-thread-2\n",
      "Running task 5 on thread pool-1-thread-1\n",
      "Running task 6 on thread pool-1-thread-5\n",
      "Running task 7 on thread pool-1-thread-4\n",
      "Running task 8 on thread pool-1-thread-3\n",
      "Running task 9 on thread pool-1-thread-2\n",
      "Running task 10 on thread pool-1-thread-5\n",
      "Running task 11 on thread pool-1-thread-4\n",
      "Running task 12 on thread pool-1-thread-3\n",
      "Running task 13 on thread pool-1-thread-1\n",
      "Running task 14 on thread pool-1-thread-2\n",
      "所有任务已完成\n"
     ]
    }
   ],
   "source": [
    "// 导入必要的类\n",
    "import java.util.concurrent.*;\n",
    "\n",
    "// 创建一个Runnable任务\n",
    "class MyRunnableTask implements Runnable {\n",
    "    private final int taskId;\n",
    "\n",
    "    public MyRunnableTask(int taskId) {\n",
    "        this.taskId = taskId;\n",
    "    }\n",
    "\n",
    "    @Override\n",
    "    public void run() {\n",
    "        System.out.println(\"Running task \" + taskId + \" on thread \" + Thread.currentThread().getName());\n",
    "        try {\n",
    "            // 模拟任务执行时间\n",
    "            Thread.sleep(1000);\n",
    "        } catch (InterruptedException e) {\n",
    "            e.printStackTrace();\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "// 使用ThreadPoolExecutor\n",
    "public class ThreadPoolExecutorExample {\n",
    "    public static void main(String[] args) {\n",
    "        // 创建一个固定大小的线程池\n",
    "        int corePoolSize = 5;\n",
    "        int maximumPoolSize = 10;\n",
    "        long keepAliveTime = 60L; // 线程空闲时间\n",
    "        TimeUnit unit = TimeUnit.SECONDS; // 时间单位\n",
    "        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(); // 工作队列\n",
    "        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 线程工厂\n",
    "        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); // 拒绝策略\n",
    "\n",
    "        ThreadPoolExecutor executor = new ThreadPoolExecutor(\n",
    "            corePoolSize,\n",
    "            maximumPoolSize,\n",
    "            keepAliveTime,\n",
    "            unit,\n",
    "            workQueue,\n",
    "            threadFactory,\n",
    "            handler\n",
    "        );\n",
    "\n",
    "        // 提交15个任务到线程池\n",
    "        for (int i = 0; i < 15; i++) {\n",
    "            Runnable task = new MyRunnableTask(i);\n",
    "            executor.execute(task);\n",
    "        }\n",
    "\n",
    "        // 关闭线程池（这会等待所有任务完成）\n",
    "        executor.shutdown();\n",
    "        while (!executor.isTerminated()) {\n",
    "        }\n",
    "        System.out.println(\"所有任务已完成\");\n",
    "    }\n",
    "}\n",
    "ThreadPoolExecutorExample.main(null);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java (jjava)",
   "language": "java",
   "name": "java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "17.0.10+11-LTS-240"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
